Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
using System;
using System.Collections.Generic;
using System.Linq;
using EPiServer;
using EPiServer.Core;
using EPiServer.Data.Entity;
using EPiServer.DataAbstraction;
using EPiServer.DataAccess;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.Security;
namespace Foundation.Features.ProjectUndo
{
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class ProjectUndoInit : IInitializableModule
{
private IContentRepository _contentRepo;
private ProjectRepository _projectRepo;
public void Initialize(InitializationEngine context)
{
if (_projectRepo == null) _projectRepo = context.Locate.Advanced.GetInstance<ProjectRepository>();
if (_contentRepo == null) _contentRepo = context.Locate.Advanced.GetInstance<IContentRepository>();
ProjectRepository.ProjectSaved += ProjectRepository_ProjectSaved;
ProjectRepository.ProjectItemsSaved += ProjectRepository_ProjectItemsSaved;
ProjectRepository.ProjectItemsDeleted += ProjectRepository_ProjectItemsDeleted;
}
private void ProjectRepository_ProjectSaved(object sender, ProjectEventArgs e)
{
if (!ShouldProcess(e.Project))
return;
if (GetRollbackProjectId(e.Project).HasValue)
return;
//We have not found an undo project so create one
_projectRepo.Save(new Project()
{
Created = DateTime.Now,
CreatedBy = "Undo: " + e.Project.Name,
Name = GetRollbackProjectName(e.Project),
Status = ProjectStatus.Active
});
}
private void ProjectRepository_ProjectItemsSaved(object sender, ProjectItemsEventArgs e)
{
if (e.ProjectItems == null)
return;
var project = _projectRepo.Get(e.ProjectItems.First().ProjectID);
if (!ShouldProcess(project))
return;
foreach (var projectItem in e.ProjectItems)
{
if (!(_contentRepo.Get<IContent>(projectItem.ContentLink) is IReadOnly originalVersion))
continue;
if (!(originalVersion.CreateWritableClone() is IContent rollbackVersion))
continue;
var rollbackProjectId = GetRollbackProjectId(project);
if (!rollbackProjectId.HasValue)
continue;
// Create a new draft of the content and add it to the rollback project
_contentRepo.Save(rollbackVersion, SaveAction.ForceNewVersion, AccessLevel.NoAccess);
var projectItems = new List<ProjectItem>
{
new ProjectItem(rollbackProjectId.Value, rollbackVersion)
};
_projectRepo.SaveItems(projectItems);
}
}
private void ProjectRepository_ProjectItemsDeleted(object sender, ProjectItemsEventArgs e)
{
if (e.ProjectItems == null)
return;
var project = _projectRepo.Get(e.ProjectItems.First().ProjectID);
if (!ShouldProcess(project))
return;
var rollbackProjectId = GetRollbackProjectId(project);
if (!rollbackProjectId.HasValue)
return;
var existingProjectItems = _projectRepo.ListItems(rollbackProjectId.Value).ToList();
if (!existingProjectItems.Any())
return;
List<int> projectItemsToDelete = new List<int>();
foreach (var projectItem in e.ProjectItems)
{
var itemToRemove = existingProjectItems
.Where(x => x.ContentLink.ID == projectItem.ContentLink.ID)
.Select(x => x.ID)
.ToList();
if (itemToRemove.Any())
{
projectItemsToDelete.AddRange(itemToRemove);
}
}
if (projectItemsToDelete.Any())
{
_projectRepo.DeleteItems(projectItemsToDelete);
}
}
private int? GetRollbackProjectId(Project originalProject)
{
var allProjects = _projectRepo.List();
if (allProjects != null)
{
foreach (var project in allProjects)
{
if (project.Name == GetRollbackProjectName(originalProject))
{
return project.ID;
}
}
}
return null;
}
private string GetRollbackProjectName(Project project) => $"{project.Name}_undo";
private bool ShouldProcess(Project project) => !project.Name.EndsWith("_undo");
public void Uninitialize(InitializationEngine context)
{
ProjectRepository.ProjectSaved -= ProjectRepository_ProjectSaved;
ProjectRepository.ProjectItemsSaved -= ProjectRepository_ProjectItemsSaved;
ProjectRepository.ProjectItemsDeleted -= ProjectRepository_ProjectItemsDeleted;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.