Added fix for RelateOnTrashComponent.MediaService_Trashed so relations are looked up before creating duplicates

Signed-off-by: Bjarke Berg <mail@bergmania.dk>
This commit is contained in:
Bjarke Berg
2020-10-12 15:22:11 +02:00
parent 928f42be2e
commit d0eb01b348
3 changed files with 72 additions and 34 deletions

View File

@@ -341,5 +341,15 @@ namespace Umbraco.Core.Services
/// </summary>
/// <param name="relationType"><see cref="IRelationType"/> to Delete Relations for</param>
void DeleteRelationsOfType(IRelationType relationType);
/// <summary>
/// Gets a relation by the unique combination of parentId, childId and relationType.
/// </summary>
/// <param name="parentId">The id of the parent item.</param>
/// <param name="childId">The id of the child item.</param>
/// <param name="relationType">The RelationType.</param>
/// <returns>The relation or null</returns>
IRelation GetByParentChildAndType(int parentId, int childId, IRelationType relationType);
}
}

View File

@@ -2,6 +2,7 @@
using Umbraco.Core.Composing;
using Umbraco.Core.Events;
using Umbraco.Core.Models;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
using Umbraco.Core.Services.Implement;
@@ -13,13 +14,20 @@ namespace Umbraco.Core.Compose
private readonly IEntityService _entityService;
private readonly ILocalizedTextService _textService;
private readonly IAuditService _auditService;
private readonly IScopeProvider _scopeProvider;
public RelateOnTrashComponent(IRelationService relationService, IEntityService entityService, ILocalizedTextService textService, IAuditService auditService)
public RelateOnTrashComponent(
IRelationService relationService,
IEntityService entityService,
ILocalizedTextService textService,
IAuditService auditService,
IScopeProvider scopeProvider)
{
_relationService = relationService;
_entityService = entityService;
_textService = textService;
_auditService = auditService;
_scopeProvider = scopeProvider;
}
public void Initialize()
@@ -68,47 +76,55 @@ namespace Umbraco.Core.Compose
private void ContentService_Trashed(IContentService sender, MoveEventArgs<IContent> e)
{
const string relationTypeAlias = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias;
var relationType = _relationService.GetRelationTypeByAlias(relationTypeAlias);
// check that the relation-type exists, if not, then recreate it
if (relationType == null)
using (var scope = _scopeProvider.CreateScope())
{
var documentObjectType = Constants.ObjectTypes.Document;
const string relationTypeName = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteName;
const string relationTypeAlias = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias;
var relationType = _relationService.GetRelationTypeByAlias(relationTypeAlias);
relationType = new RelationType(relationTypeName, relationTypeAlias, false, documentObjectType, documentObjectType);
_relationService.Save(relationType);
}
foreach (var item in e.MoveInfoCollection)
{
var originalPath = item.OriginalPath.ToDelimitedList();
var originalParentId = originalPath.Count > 2
? int.Parse(originalPath[originalPath.Count - 2])
: Constants.System.Root;
//before we can create this relation, we need to ensure that the original parent still exists which
//may not be the case if the encompassing transaction also deleted it when this item was moved to the bin
if (_entityService.Exists(originalParentId))
// check that the relation-type exists, if not, then recreate it
if (relationType == null)
{
// Add a relation for the item being deleted, so that we can know the original parent for if we need to restore later
var relation = new Relation(originalParentId, item.Entity.Id, relationType);
_relationService.Save(relation);
var documentObjectType = Constants.ObjectTypes.Document;
const string relationTypeName =
Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteName;
_auditService.Add(AuditType.Delete,
item.Entity.WriterId,
item.Entity.Id,
ObjectTypes.GetName(UmbracoObjectTypes.Document),
string.Format(_textService.Localize(
"recycleBin/contentTrashed"),
item.Entity.Id, originalParentId));
relationType = new RelationType(relationTypeName, relationTypeAlias, false, documentObjectType,
documentObjectType);
_relationService.Save(relationType);
}
foreach (var item in e.MoveInfoCollection)
{
var originalPath = item.OriginalPath.ToDelimitedList();
var originalParentId = originalPath.Count > 2
? int.Parse(originalPath[originalPath.Count - 2])
: Constants.System.Root;
//before we can create this relation, we need to ensure that the original parent still exists which
//may not be the case if the encompassing transaction also deleted it when this item was moved to the bin
if (_entityService.Exists(originalParentId))
{
// Add a relation for the item being deleted, so that we can know the original parent for if we need to restore later
var relation = _relationService.GetByParentChildAndType(originalParentId, item.Entity.Id, relationType) ??
new Relation(originalParentId, item.Entity.Id, relationType);
_relationService.Save(relation);
_auditService.Add(AuditType.Delete,
item.Entity.WriterId,
item.Entity.Id,
ObjectTypes.GetName(UmbracoObjectTypes.Document),
string.Format(_textService.Localize(
"recycleBin/contentTrashed"),
item.Entity.Id, originalParentId));
}
}
scope.Complete();
}
}
private void MediaService_Trashed(IMediaService sender, MoveEventArgs<IMedia> e)
public void MediaService_Trashed(IMediaService sender, MoveEventArgs<IMedia> e)
{
const string relationTypeAlias = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias;
var relationType = _relationService.GetRelationTypeByAlias(relationTypeAlias);

View File

@@ -543,6 +543,18 @@ namespace Umbraco.Core.Services.Implement
}
}
/// <inheritdoc />
public IRelation GetByParentChildAndType(int parentId, int childId, IRelationType relationType)
{
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
{
var query = Query<IRelation>().Where(x => x.ParentId == parentId &&
x.ChildId == childId &&
x.RelationTypeId == relationType.Id);
return _relationRepository.Get(query).FirstOrDefault();
}
}
#region Private Methods
private IRelationType GetRelationType(string relationTypeAlias)