Fixes: U4-3795 Cannot create content with a tag editor when the tag property belongs to an inherited doc type & U4-3786 Multi-level document types fail
This commit is contained in:
@@ -34,7 +34,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// Assigns the given tags to a content item's property
|
||||
/// </summary>
|
||||
/// <param name="contentId"></param>
|
||||
/// <param name="propertyTypeAlias"></param>
|
||||
/// <param name="propertyTypeId"></param>
|
||||
/// <param name="tags">The tags to assign</param>
|
||||
/// <param name="replaceTags">
|
||||
/// If set to true, this will replace all tags with the given tags,
|
||||
@@ -44,14 +44,14 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <remarks>
|
||||
/// This can also be used to remove all tags from a property by specifying replaceTags = true and an empty tag list.
|
||||
/// </remarks>
|
||||
void AssignTagsToProperty(int contentId, string propertyTypeAlias, IEnumerable<ITag> tags, bool replaceTags);
|
||||
void AssignTagsToProperty(int contentId, int propertyTypeId, IEnumerable<ITag> tags, bool replaceTags);
|
||||
|
||||
/// <summary>
|
||||
/// Removes any of the given tags from the property association
|
||||
/// </summary>
|
||||
/// <param name="contentId"></param>
|
||||
/// <param name="propertyTypeAlias"></param>
|
||||
/// <param name="propertyTypeId"></param>
|
||||
/// <param name="tags">The tags to remove from the property</param>
|
||||
void RemoveTagsFromProperty(int contentId, string propertyTypeAlias, IEnumerable<ITag> tags);
|
||||
void RemoveTagsFromProperty(int contentId, int propertyTypeId, IEnumerable<ITag> tags);
|
||||
}
|
||||
}
|
||||
@@ -230,7 +230,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// Assigns the given tags to a content item's property
|
||||
/// </summary>
|
||||
/// <param name="contentId"></param>
|
||||
/// <param name="propertyTypeAlias"></param>
|
||||
/// <param name="propertyTypeId"></param>
|
||||
/// <param name="tags">The tags to assign</param>
|
||||
/// <param name="replaceTags">
|
||||
/// If set to true, this will replace all tags with the given tags,
|
||||
@@ -240,7 +240,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <remarks>
|
||||
/// This can also be used to remove all tags from a property by specifying replaceTags = true and an empty tag list.
|
||||
/// </remarks>
|
||||
public void AssignTagsToProperty(int contentId, string propertyTypeAlias, IEnumerable<ITag> tags, bool replaceTags)
|
||||
//public void AssignTagsToProperty(int contentId, string propertyTypeAlias, IEnumerable<ITag> tags, bool replaceTags)
|
||||
public void AssignTagsToProperty(int contentId, int propertyTypeId, IEnumerable<ITag> tags, bool replaceTags)
|
||||
{
|
||||
//First we need to ensure there are no duplicates
|
||||
var asArray = tags.Distinct(new TagComparer()).ToArray();
|
||||
@@ -251,8 +252,6 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
return;
|
||||
}
|
||||
|
||||
var propertyTypeId = EnsureContentProperty(contentId, propertyTypeAlias);
|
||||
|
||||
//next check if we're removing all of the tags
|
||||
if (asArray.Length == 0 && replaceTags)
|
||||
{
|
||||
@@ -310,7 +309,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
"left outer join cmsTagRelationship ",
|
||||
"on (cmsTagRelationship.TagId = NewTagsSet.Id and cmsTagRelationship.nodeId = ",
|
||||
contentId,
|
||||
"and cmsTagRelationship.propertyTypeId = ",
|
||||
" and cmsTagRelationship.propertyTypeId = ",
|
||||
propertyTypeId,
|
||||
") ",
|
||||
"where cmsTagRelationship.tagId is null ");
|
||||
@@ -327,12 +326,10 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// Removes any of the given tags from the property association
|
||||
/// </summary>
|
||||
/// <param name="contentId"></param>
|
||||
/// <param name="propertyTypeAlias"></param>
|
||||
/// <param name="propertyTypeId"></param>
|
||||
/// <param name="tags">The tags to remove from the property</param>
|
||||
public void RemoveTagsFromProperty(int contentId, string propertyTypeAlias, IEnumerable<ITag> tags)
|
||||
public void RemoveTagsFromProperty(int contentId, int propertyTypeId, IEnumerable<ITag> tags)
|
||||
{
|
||||
var propertyTypeId = EnsureContentProperty(contentId, propertyTypeAlias);
|
||||
|
||||
var tagSetSql = GetTagSet(tags);
|
||||
|
||||
var deleteSql = string.Concat("DELETE FROM cmsTagRelationship WHERE nodeId = ",
|
||||
@@ -396,36 +393,5 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures the content and property alias exist, then returns the property type id for the alias
|
||||
/// </summary>
|
||||
/// <param name="contentId"></param>
|
||||
/// <param name="propertyAlias"></param>
|
||||
/// <returns></returns>
|
||||
private int EnsureContentProperty(int contentId, string propertyAlias)
|
||||
{
|
||||
//ensure that there's content and a property to assign - NOTE: we cannot use the content repository here
|
||||
// because the content repository requires one of us TagsRepository instance, then we'll have circular dependencies
|
||||
// instead we'll just look it up ourselves.
|
||||
|
||||
var sql = new Sql()
|
||||
.Select("cmsPropertyType.id")
|
||||
.From<ContentDto>()
|
||||
.InnerJoin<ContentTypeDto>()
|
||||
.On<ContentTypeDto, ContentDto>(left => left.NodeId, right => right.ContentTypeId)
|
||||
.InnerJoin<PropertyTypeDto>()
|
||||
.On<PropertyTypeDto, ContentTypeDto>(left => left.ContentTypeId, right => right.NodeId)
|
||||
.Where<ContentDto>(dto => dto.NodeId == contentId)
|
||||
.Where<PropertyTypeDto>(dto => dto.Alias == propertyAlias);
|
||||
|
||||
var result = Database.Fetch<int>(sql).ToArray();
|
||||
|
||||
if (result.Length == 0)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot modify tags for content id " + contentId + " and property " + propertyAlias + " because the content item does not exist with this property");
|
||||
}
|
||||
|
||||
return result.First();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,7 +106,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
//remove the specific tags
|
||||
tagRepo.RemoveTagsFromProperty(
|
||||
entity.Id,
|
||||
tagProp.Alias,
|
||||
tagProp.PropertyTypeId,
|
||||
tagProp.TagSupport.Tags.Select(x => new Tag { Text = x.Item1, Group = x.Item2 }));
|
||||
}
|
||||
else
|
||||
@@ -114,7 +114,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
//assign the tags
|
||||
tagRepo.AssignTagsToProperty(
|
||||
entity.Id,
|
||||
tagProp.Alias,
|
||||
tagProp.PropertyTypeId,
|
||||
tagProp.TagSupport.Tags.Select(x => new Tag { Text = x.Item1, Group = x.Item2 }),
|
||||
tagProp.TagSupport.Behavior == PropertyTagBehavior.Replace);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,18 @@ namespace Umbraco.Core.Services
|
||||
|
||||
#region IMemberService Implementation
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a member with the username exists
|
||||
/// </summary>
|
||||
/// <param name="username"></param>
|
||||
/// <returns></returns>
|
||||
public bool Exists(string username)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
return repository.Exists(username);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a member with the id exists
|
||||
|
||||
@@ -104,18 +104,6 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Cannot_Assign_Tags_To_Non_Existing_Property()
|
||||
{
|
||||
var provider = new PetaPocoUnitOfWorkProvider();
|
||||
var unitOfWork = provider.GetUnitOfWork();
|
||||
using (var repository = CreateRepository(unitOfWork))
|
||||
{
|
||||
Assert.Throws<InvalidOperationException>(() => repository.AssignTagsToProperty(1234, "hello", Enumerable.Empty<ITag>(), true));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Create_Tag_Relations()
|
||||
{
|
||||
@@ -136,7 +124,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
{
|
||||
repository.AssignTagsToProperty(
|
||||
content.Id,
|
||||
contentType.PropertyTypes.First().Alias,
|
||||
contentType.PropertyTypes.First().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag1", Group = "test"},
|
||||
@@ -168,7 +156,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
{
|
||||
repository.AssignTagsToProperty(
|
||||
content.Id,
|
||||
contentType.PropertyTypes.First().Alias,
|
||||
contentType.PropertyTypes.First().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag1", Group = "test"},
|
||||
@@ -177,7 +165,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
|
||||
repository.AssignTagsToProperty(
|
||||
content.Id,
|
||||
contentType.PropertyTypes.First().Alias,
|
||||
contentType.PropertyTypes.First().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag3", Group = "test"},
|
||||
@@ -209,7 +197,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
{
|
||||
repository.AssignTagsToProperty(
|
||||
content.Id,
|
||||
contentType.PropertyTypes.First().Alias,
|
||||
contentType.PropertyTypes.First().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag1", Group = "test"},
|
||||
@@ -218,7 +206,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
|
||||
repository.AssignTagsToProperty(
|
||||
content.Id,
|
||||
contentType.PropertyTypes.First().Alias,
|
||||
contentType.PropertyTypes.First().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag3", Group = "test"},
|
||||
@@ -253,7 +241,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
{
|
||||
repository.AssignTagsToProperty(
|
||||
content.Id,
|
||||
contentType.PropertyTypes.First().Alias,
|
||||
contentType.PropertyTypes.First().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag1", Group = "test"},
|
||||
@@ -262,7 +250,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
|
||||
repository.AssignTagsToProperty(
|
||||
content.Id,
|
||||
contentType.PropertyTypes.First().Alias,
|
||||
contentType.PropertyTypes.First().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag2", Group = "test"},
|
||||
@@ -295,7 +283,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
{
|
||||
repository.AssignTagsToProperty(
|
||||
content.Id,
|
||||
contentType.PropertyTypes.First().Alias,
|
||||
contentType.PropertyTypes.First().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag1", Group = "test"},
|
||||
@@ -304,7 +292,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
|
||||
repository.AssignTagsToProperty(
|
||||
content.Id,
|
||||
contentType.PropertyTypes.First().Alias,
|
||||
contentType.PropertyTypes.First().Id,
|
||||
Enumerable.Empty<ITag>(), true);
|
||||
|
||||
var result = repository.GetTagsForEntity(content.Id);
|
||||
@@ -333,7 +321,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
{
|
||||
repository.AssignTagsToProperty(
|
||||
content.Id,
|
||||
contentType.PropertyTypes.First().Alias,
|
||||
contentType.PropertyTypes.First().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag1", Group = "test"},
|
||||
@@ -344,7 +332,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
|
||||
repository.RemoveTagsFromProperty(
|
||||
content.Id,
|
||||
contentType.PropertyTypes.First().Alias,
|
||||
contentType.PropertyTypes.First().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag2", Group = "test"},
|
||||
@@ -381,7 +369,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
{
|
||||
repository.AssignTagsToProperty(
|
||||
content1.Id,
|
||||
contentType.PropertyTypes.First().Alias,
|
||||
contentType.PropertyTypes.First().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag1", Group = "test"},
|
||||
@@ -392,7 +380,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
|
||||
repository.AssignTagsToProperty(
|
||||
content2.Id,
|
||||
contentType.PropertyTypes.First().Alias,
|
||||
contentType.PropertyTypes.First().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag1", Group = "test"},
|
||||
@@ -427,7 +415,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
{
|
||||
repository.AssignTagsToProperty(
|
||||
content1.Id,
|
||||
contentType.PropertyTypes.First().Alias,
|
||||
contentType.PropertyTypes.First().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag1", Group = "test"},
|
||||
@@ -438,7 +426,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
|
||||
repository.AssignTagsToProperty(
|
||||
content2.Id,
|
||||
contentType.PropertyTypes.First().Alias,
|
||||
contentType.PropertyTypes.First().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag1", Group = "test"},
|
||||
@@ -471,7 +459,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
{
|
||||
repository.AssignTagsToProperty(
|
||||
content1.Id,
|
||||
contentType.PropertyTypes.First().Alias,
|
||||
contentType.PropertyTypes.First().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag1", Group = "test"},
|
||||
@@ -482,7 +470,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
|
||||
repository.AssignTagsToProperty(
|
||||
content1.Id,
|
||||
contentType.PropertyTypes.Last().Alias,
|
||||
contentType.PropertyTypes.Last().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag1", Group = "test"},
|
||||
@@ -518,7 +506,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
{
|
||||
repository.AssignTagsToProperty(
|
||||
content1.Id,
|
||||
contentType.PropertyTypes.First().Alias,
|
||||
contentType.PropertyTypes.First().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag1", Group = "test"},
|
||||
@@ -529,7 +517,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
|
||||
repository.AssignTagsToProperty(
|
||||
content1.Id,
|
||||
contentType.PropertyTypes.Last().Alias,
|
||||
contentType.PropertyTypes.Last().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag1", Group = "test"},
|
||||
@@ -575,7 +563,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
{
|
||||
repository.AssignTagsToProperty(
|
||||
content1.Id,
|
||||
contentType.PropertyTypes.First().Alias,
|
||||
contentType.PropertyTypes.First().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag1", Group = "test"},
|
||||
@@ -585,7 +573,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
|
||||
repository.AssignTagsToProperty(
|
||||
media1.Id,
|
||||
mediaType.PropertyTypes.Last().Alias,
|
||||
mediaType.PropertyTypes.Last().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag1", Group = "test"},
|
||||
@@ -631,7 +619,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
{
|
||||
repository.AssignTagsToProperty(
|
||||
content1.Id,
|
||||
contentType.PropertyTypes.First().Alias,
|
||||
contentType.PropertyTypes.First().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag1", Group = "test"},
|
||||
@@ -642,7 +630,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
|
||||
repository.AssignTagsToProperty(
|
||||
media1.Id,
|
||||
mediaType.PropertyTypes.Last().Alias,
|
||||
mediaType.PropertyTypes.Last().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag1", Group = "test"},
|
||||
@@ -680,7 +668,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
{
|
||||
repository.AssignTagsToProperty(
|
||||
content1.Id,
|
||||
contentType.PropertyTypes.First().Alias,
|
||||
contentType.PropertyTypes.First().Id,
|
||||
new[]
|
||||
{
|
||||
new Tag {Text = "tag1", Group = "test"},
|
||||
|
||||
@@ -154,25 +154,18 @@ namespace Umbraco.Web.Models.Mapping
|
||||
foreach (var propertyGroups in content.PropertyGroups.OrderBy(x => x.SortOrder).GroupBy(x => x.Name))
|
||||
{
|
||||
var aggregateProperties = new List<ContentPropertyDisplay>();
|
||||
|
||||
//there will always be one group with a null parent id (the top-most)
|
||||
//then we'll iterate over all of the groups and ensure the properties are
|
||||
//added in order so that when they render they are rendered with highest leve
|
||||
//parent properties first.
|
||||
int? currentParentId = null;
|
||||
for (var i = 0; i < propertyGroups.Count(); i++)
|
||||
|
||||
//add the properties from each composite property group
|
||||
foreach (var current in propertyGroups)
|
||||
{
|
||||
var current = propertyGroups.Single(x => x.ParentId == currentParentId);
|
||||
|
||||
var propsForGroup = content.GetPropertiesForGroup(current)
|
||||
.Where(x => IgnoreProperties.Contains(x.Alias) == false); //don't include ignored props
|
||||
|
||||
aggregateProperties.AddRange(
|
||||
Mapper.Map<IEnumerable<Property>, IEnumerable<ContentPropertyDisplay>>(
|
||||
propsForGroup));
|
||||
currentParentId = current.Id;
|
||||
}
|
||||
|
||||
|
||||
//then we'll just use the root group's data to make the composite tab
|
||||
var rootGroup = propertyGroups.Single(x => x.ParentId == null);
|
||||
aggregateTabs.Add(new Tab<ContentPropertyDisplay>
|
||||
|
||||
Reference in New Issue
Block a user