This commit is contained in:
Sebastiaan Janssen
2013-01-18 11:45:42 -01:00
5 changed files with 127 additions and 43 deletions

View File

@@ -280,6 +280,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
var parent = Database.First<NodeDto>("WHERE id = @ParentId", new { ParentId = entity.ParentId });
entity.Path = string.Concat(parent.Path, ",", entity.Id);
entity.Level = parent.Level + 1;
var maxSortOrder = Database.ExecuteScalar<int>("SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId", new { ParentId = entity.ParentId });
entity.SortOrder = maxSortOrder;
}

View File

@@ -245,6 +245,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
var parent = Database.First<NodeDto>("WHERE id = @ParentId", new { ParentId = entity.ParentId });
entity.Path = string.Concat(parent.Path, ",", entity.Id);
entity.Level = parent.Level + 1;
var maxSortOrder = Database.ExecuteScalar<int>("SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId", new { ParentId = entity.ParentId });
entity.SortOrder = maxSortOrder;
}

View File

@@ -894,56 +894,76 @@ namespace Umbraco.Core.Services
}
/// <summary>
/// Moves an <see cref="IContent"/> object to a new location by changing its parent id.
/// </summary>
/// <remarks>
/// If the <see cref="IContent"/> object is already published it will be
/// published after being moved to its new location. Otherwise it'll just
/// be saved with a new parent id.
/// </remarks>
/// <param name="content">The <see cref="IContent"/> to move</param>
/// <param name="parentId">Id of the Content's new Parent</param>
/// <param name="userId">Optional Id of the User moving the Content</param>
public void Move(IContent content, int parentId, int userId = -1)
{
//This ensures that the correct method is called if this method is used to Move to recycle bin.
if (parentId == -20)
{
MoveToRecycleBin(content, userId);
return;
}
/// Moves an <see cref="IContent"/> object to a new location by changing its parent id.
/// </summary>
/// <remarks>
/// If the <see cref="IContent"/> object is already published it will be
/// published after being moved to its new location. Otherwise it'll just
/// be saved with a new parent id.
/// </remarks>
/// <param name="content">The <see cref="IContent"/> to move</param>
/// <param name="parentId">Id of the Content's new Parent</param>
/// <param name="userId">Optional Id of the User moving the Content</param>
public void Move(IContent content, int parentId, int userId = -1)
{
//This ensures that the correct method is called if this method is used to Move to recycle bin.
if (parentId == -20)
{
MoveToRecycleBin(content, userId);
return;
}
if (Moving.IsRaisedEventCancelled(new MoveEventArgs<IContent>(content, parentId), this))
return;
SetWriter(content, userId);
if (Moving.IsRaisedEventCancelled(new MoveEventArgs<IContent>(content, parentId), this))
return;
//If Content is being moved away from Recycle Bin, its state should be un-trashed
if (content.Trashed && parentId != -20)
{
content.ChangeTrashedState(false, parentId);
}
else
{
content.ParentId = parentId;
}
SetWriter(content, userId);
//If Content is published, it should be (re)published from its new location
if (content.Published)
{
SaveAndPublish(content, userId);
}
else
{
Save(content, userId);
}
//If Content is being moved away from Recycle Bin, its state should be un-trashed
if (content.Trashed && parentId != -20)
{
content.ChangeTrashedState(false, parentId);
}
else
{
content.ParentId = parentId;
}
Moved.RaiseEvent(new MoveEventArgs<IContent>(content, false, parentId), this);
//If Content is published, it should be (re)published from its new location
if (content.Published)
{
SaveAndPublish(content, userId);
}
else
{
Save(content, userId);
}
//Ensure that Path and Level is updated on children
var children = GetChildren(content.Id);
if (children.Any())
{
var parentPath = content.Path;
var parentLevel = content.Level;
var updatedDescendents = UpdatePathAndLevelOnChildren(children, parentPath, parentLevel);
//collection of descendents that needs to be saved and published
var descendentsToSaveAndPublish = updatedDescendents.Where(x => x.Published);
foreach (var c in descendentsToSaveAndPublish)
{
SaveAndPublish(c, userId);
}
//collection of descendents that only needs to be saved
var descendentsToSave = updatedDescendents.Where(x => x.Published == false);
Save(descendentsToSave, userId);
}
Moved.RaiseEvent(new MoveEventArgs<IContent>(content, false, parentId), this);
Audit.Add(AuditTypes.Move, "Move Content performed by user", userId == -1 ? 0 : userId, content.Id);
}
/// <summary>
/// <summary>
/// Empties the Recycle Bin by deleting all <see cref="IContent"/> that resides in the bin
/// </summary>
public void EmptyRecycleBin()
@@ -1202,6 +1222,32 @@ namespace Umbraco.Core.Services
return true;
}
/// <summary>
/// Updates the Path and Level on a collection of <see cref="IContent"/> objects
/// based on the Parent's Path and Level.
/// </summary>
/// <param name="children">Collection of <see cref="IContent"/> objects to update</param>
/// <param name="parentPath">Path of the Parent content</param>
/// <param name="parentLevel">Level of the Parent content</param>
/// <returns>Collection of updated <see cref="IContent"/> objects</returns>
private List<IContent> UpdatePathAndLevelOnChildren(IEnumerable<IContent> children, string parentPath, int parentLevel)
{
var list = new List<IContent>();
foreach (var child in children)
{
child.Path = string.Concat(parentPath, ",", child.Id);
child.Level = parentLevel + 1;
list.Add(child);
var grandkids = GetChildren(child.Id);
if (grandkids.Any())
{
list.AddRange(UpdatePathAndLevelOnChildren(grandkids, child.Path, child.Level));
}
}
return list;
}
/// <summary>
/// Updates a content object with the User (id), who created the content.
/// </summary>

View File

@@ -276,6 +276,16 @@ namespace Umbraco.Core.Services
media.ParentId = parentId;
Save(media, userId);
//Ensure that Path and Level is updated on children
var children = GetChildren(media.Id);
if (children.Any())
{
var parentPath = media.Path;
var parentLevel = media.Level;
var updatedDescendents = UpdatePathAndLevelOnChildren(children, parentPath, parentLevel);
Save(updatedDescendents, userId);
}
Moved.RaiseEvent(new MoveEventArgs<IMedia>(media, false, parentId), this);
Audit.Add(AuditTypes.Move, "Move Media performed by user", userId == -1 ? 0 : userId, media.Id);
@@ -513,6 +523,32 @@ namespace Umbraco.Core.Services
_httpContext = httpContext;
}
/// <summary>
/// Updates the Path and Level on a collection of <see cref="IMedia"/> objects
/// based on the Parent's Path and Level.
/// </summary>
/// <param name="children">Collection of <see cref="IMedia"/> objects to update</param>
/// <param name="parentPath">Path of the Parent media</param>
/// <param name="parentLevel">Level of the Parent media</param>
/// <returns>Collection of updated <see cref="IMedia"/> objects</returns>
private List<IMedia> UpdatePathAndLevelOnChildren(IEnumerable<IMedia> children, string parentPath, int parentLevel)
{
var list = new List<IMedia>();
foreach (var child in children)
{
child.Path = string.Concat(parentPath, ",", child.Id);
child.Level = parentLevel + 1;
list.Add(child);
var grandkids = GetChildren(child.Id);
if (grandkids.Any())
{
list.AddRange(UpdatePathAndLevelOnChildren(grandkids, child.Path, child.Level));
}
}
return list;
}
/// <summary>
/// Updates a media object with the User (id), who created the content.
/// </summary>

View File

@@ -1224,7 +1224,7 @@ namespace umbraco.cms.businesslogic
temporaryList.Sort((a, b) => a.SortOrder.CompareTo(b.SortOrder));
// now that we aren't going to modify the list, we can set it to the class-scoped variable.
m_VirtualTabs = temporaryList;
m_VirtualTabs = temporaryList.DistinctBy(x => x.Id).ToList();
}
private void populateMasterContentTypes(PropertyType pt, int docTypeId)