diff --git a/src/Umbraco.Core/Services/ContentTypeServiceExtensions.cs b/src/Umbraco.Core/Services/ContentTypeServiceExtensions.cs
index fd475c558a..37f1e5127f 100644
--- a/src/Umbraco.Core/Services/ContentTypeServiceExtensions.cs
+++ b/src/Umbraco.Core/Services/ContentTypeServiceExtensions.cs
@@ -37,12 +37,14 @@ namespace Umbraco.Core.Services
/// This is required because in the case of creating/modifying a content type because new property types being added to it are not yet persisted so cannot
/// be looked up via the db, they need to be passed in.
///
+ /// Wether the composite content types should be applicable for an element type
///
internal static ContentTypeAvailableCompositionsResults GetAvailableCompositeContentTypes(this IContentTypeService ctService,
IContentTypeComposition source,
IContentTypeComposition[] allContentTypes,
string[] filterContentTypes = null,
- string[] filterPropertyTypes = null)
+ string[] filterPropertyTypes = null,
+ bool isElement = false)
{
filterContentTypes = filterContentTypes == null
? Array.Empty()
@@ -61,7 +63,7 @@ namespace Umbraco.Core.Services
.Select(c => c.Alias)
.Union(filterPropertyTypes)
.ToArray();
-
+
var sourceId = source?.Id ?? 0;
// find out if any content type uses this content type
@@ -79,8 +81,9 @@ namespace Umbraco.Core.Services
x => x.Id));
// usable types are those that are top-level
+ // do not allow element types to be composed by non-element types as this will break the model generation in ModelsBuilder
var usableContentTypes = allContentTypes
- .Where(x => x.ContentTypeComposition.Any() == false).ToArray();
+ .Where(x => x.ContentTypeComposition.Any() == false && (isElement == false || x.IsElement)).ToArray();
foreach (var x in usableContentTypes)
list.Add(x);
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbgroupsbuilder.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbgroupsbuilder.directive.js
index 7c4af11022..ba479429f1 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbgroupsbuilder.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbgroupsbuilder.directive.js
@@ -257,7 +257,7 @@
view: "views/common/infiniteeditors/compositions/compositions.html",
size: "small",
submit: function() {
-
+
// make sure that all tabs has an init property
if (scope.model.groups.length !== 0) {
angular.forEach(scope.model.groups, function(group) {
@@ -341,7 +341,7 @@
scope.compositionsButtonState = "busy";
$q.all([
//get available composite types
- availableContentTypeResource(scope.model.id, [], propAliasesExisting).then(function (result) {
+ availableContentTypeResource(scope.model.id, [], propAliasesExisting, scope.model.isElement).then(function (result) {
setupAvailableContentTypesModel(result);
}),
//get where used document types
diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js
index 4e4c8d2eb5..64accc18c1 100644
--- a/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js
+++ b/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js
@@ -16,7 +16,7 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter, loca
'Failed to retrieve count');
},
- getAvailableCompositeContentTypes: function (contentTypeId, filterContentTypes, filterPropertyTypes) {
+ getAvailableCompositeContentTypes: function (contentTypeId, filterContentTypes, filterPropertyTypes, isElement) {
if (!filterContentTypes) {
filterContentTypes = [];
}
@@ -27,7 +27,8 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter, loca
var query = {
contentTypeId: contentTypeId,
filterContentTypes: filterContentTypes,
- filterPropertyTypes: filterPropertyTypes
+ filterPropertyTypes: filterPropertyTypes,
+ isElement: isElement
};
return umbRequestHelper.resourcePromise(
diff --git a/src/Umbraco.Web/Editors/ContentTypeController.cs b/src/Umbraco.Web/Editors/ContentTypeController.cs
index cf8b6c3859..e99cbdca4a 100644
--- a/src/Umbraco.Web/Editors/ContentTypeController.cs
+++ b/src/Umbraco.Web/Editors/ContentTypeController.cs
@@ -132,7 +132,7 @@ namespace Umbraco.Web.Editors
[HttpPost]
public HttpResponseMessage GetAvailableCompositeContentTypes(GetAvailableCompositionsFilter filter)
{
- var result = PerformGetAvailableCompositeContentTypes(filter.ContentTypeId, UmbracoObjectTypes.DocumentType, filter.FilterContentTypes, filter.FilterPropertyTypes)
+ var result = PerformGetAvailableCompositeContentTypes(filter.ContentTypeId, UmbracoObjectTypes.DocumentType, filter.FilterContentTypes, filter.FilterPropertyTypes, filter.IsElement)
.Select(x => new
{
contentType = x.Item1,
diff --git a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs
index 9b8a098e21..2b3990c7a1 100644
--- a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs
+++ b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs
@@ -53,11 +53,13 @@ namespace Umbraco.Web.Editors
/// be looked up via the db, they need to be passed in.
///
///
+ /// Wether the composite content types should be applicable for an element type
///
protected IEnumerable> PerformGetAvailableCompositeContentTypes(int contentTypeId,
UmbracoObjectTypes type,
string[] filterContentTypes,
- string[] filterPropertyTypes)
+ string[] filterPropertyTypes,
+ bool isElement)
{
IContentTypeComposition source = null;
@@ -98,7 +100,7 @@ namespace Umbraco.Web.Editors
throw new ArgumentOutOfRangeException("The entity type was not a content type");
}
- var availableCompositions = Services.ContentTypeService.GetAvailableCompositeContentTypes(source, allContentTypes, filterContentTypes, filterPropertyTypes);
+ var availableCompositions = Services.ContentTypeService.GetAvailableCompositeContentTypes(source, allContentTypes, filterContentTypes, filterPropertyTypes, isElement);
diff --git a/src/Umbraco.Web/Editors/MediaTypeController.cs b/src/Umbraco.Web/Editors/MediaTypeController.cs
index 24d8f696b6..43569c77e2 100644
--- a/src/Umbraco.Web/Editors/MediaTypeController.cs
+++ b/src/Umbraco.Web/Editors/MediaTypeController.cs
@@ -110,7 +110,7 @@ namespace Umbraco.Web.Editors
[HttpPost]
public HttpResponseMessage GetAvailableCompositeMediaTypes(GetAvailableCompositionsFilter filter)
{
- var result = PerformGetAvailableCompositeContentTypes(filter.ContentTypeId, UmbracoObjectTypes.MediaType, filter.FilterContentTypes, filter.FilterPropertyTypes)
+ var result = PerformGetAvailableCompositeContentTypes(filter.ContentTypeId, UmbracoObjectTypes.MediaType, filter.FilterContentTypes, filter.FilterPropertyTypes, filter.IsElement)
.Select(x => new
{
contentType = x.Item1,
diff --git a/src/Umbraco.Web/Editors/MemberTypeController.cs b/src/Umbraco.Web/Editors/MemberTypeController.cs
index f406988ae5..fffead9155 100644
--- a/src/Umbraco.Web/Editors/MemberTypeController.cs
+++ b/src/Umbraco.Web/Editors/MemberTypeController.cs
@@ -89,7 +89,7 @@ namespace Umbraco.Web.Editors
[FromUri]string[] filterContentTypes,
[FromUri]string[] filterPropertyTypes)
{
- var result = PerformGetAvailableCompositeContentTypes(contentTypeId, UmbracoObjectTypes.MemberType, filterContentTypes, filterPropertyTypes)
+ var result = PerformGetAvailableCompositeContentTypes(contentTypeId, UmbracoObjectTypes.MemberType, filterContentTypes, filterPropertyTypes, false)
.Select(x => new
{
contentType = x.Item1,
diff --git a/src/Umbraco.Web/Models/ContentEditing/GetAvailableCompositionsFilter.cs b/src/Umbraco.Web/Models/ContentEditing/GetAvailableCompositionsFilter.cs
index 38442f6da5..b1528db697 100644
--- a/src/Umbraco.Web/Models/ContentEditing/GetAvailableCompositionsFilter.cs
+++ b/src/Umbraco.Web/Models/ContentEditing/GetAvailableCompositionsFilter.cs
@@ -16,5 +16,10 @@
/// along with any content types that have matching property types that are included in the filtered content types
///
public string[] FilterContentTypes { get; set; }
+
+ ///
+ /// Wether the content type is currently marked as an element type
+ ///
+ public bool IsElement { get; set; }
}
}