2012-11-07 13:56:52 -01:00
|
|
|
using System;
|
2012-10-03 12:51:32 -02:00
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
2012-11-12 08:39:29 -01:00
|
|
|
using System.Web;
|
2012-10-29 14:28:16 -01:00
|
|
|
using Umbraco.Core.Logging;
|
2012-10-03 12:51:32 -02:00
|
|
|
using Umbraco.Core.Models;
|
2012-10-31 15:15:02 -01:00
|
|
|
using Umbraco.Core.Models.EntityBase;
|
2012-10-03 12:51:32 -02:00
|
|
|
using Umbraco.Core.Persistence;
|
2012-10-10 12:13:23 -02:00
|
|
|
using Umbraco.Core.Persistence.Querying;
|
|
|
|
|
using Umbraco.Core.Persistence.Repositories;
|
|
|
|
|
using Umbraco.Core.Persistence.UnitOfWork;
|
2012-11-06 10:47:14 -01:00
|
|
|
using Umbraco.Core.Publishing;
|
2012-10-03 12:51:32 -02:00
|
|
|
|
2012-11-12 07:40:11 -01:00
|
|
|
namespace Umbraco.Core.Services
|
2012-10-03 12:51:32 -02:00
|
|
|
{
|
2012-10-24 08:36:45 -02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Represents the Content Service, which is an easy access to operations involving <see cref="IContent"/>
|
|
|
|
|
/// </summary>
|
2012-10-03 12:51:32 -02:00
|
|
|
public class ContentService : IContentService
|
|
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
|
|
|
|
|
private readonly IPublishingStrategy _publishingStrategy;
|
|
|
|
|
private readonly IUserService _userService;
|
2012-11-12 08:39:29 -01:00
|
|
|
private HttpContextBase _httpContext;
|
2012-12-11 12:03:36 +05:00
|
|
|
|
|
|
|
|
public ContentService(IDatabaseUnitOfWorkProvider provider, IPublishingStrategy publishingStrategy)
|
2012-10-03 12:51:32 -02:00
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
_uowProvider = provider;
|
|
|
|
|
_publishingStrategy = publishingStrategy;
|
2012-10-10 12:13:23 -02:00
|
|
|
}
|
|
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
internal ContentService(IDatabaseUnitOfWorkProvider provider, IPublishingStrategy publishingStrategy, IUserService userService)
|
2012-11-12 08:39:29 -01:00
|
|
|
{
|
|
|
|
|
_publishingStrategy = publishingStrategy;
|
|
|
|
|
_userService = userService;
|
2012-12-11 12:03:36 +05:00
|
|
|
_uowProvider = provider;
|
2012-11-12 08:39:29 -01:00
|
|
|
}
|
|
|
|
|
|
2012-11-12 08:00:51 -01:00
|
|
|
//TODO Add GetLatestUnpublishedVersions(int id){}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Creates an <see cref="IContent"/> object using the alias of the <see cref="IContentType"/>
|
|
|
|
|
/// that this Content is based on.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="parentId">Id of Parent for content</param>
|
|
|
|
|
/// <param name="contentTypeAlias">Alias of the <see cref="IContentType"/></param>
|
2012-11-05 14:42:21 -01:00
|
|
|
/// <param name="userId">Optional id of the user creating the content</param>
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <returns><see cref="IContent"/></returns>
|
2012-11-05 14:42:21 -01:00
|
|
|
public IContent CreateContent(int parentId, string contentTypeAlias, int userId = -1)
|
2012-10-10 12:13:23 -02:00
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
var uow = _uowProvider.GetUnitOfWork();
|
|
|
|
|
var repository = RepositoryResolver.Current.Factory.CreateContentTypeRepository(uow);
|
2012-10-10 12:13:23 -02:00
|
|
|
var query = Query<IContentType>.Builder.Where(x => x.Alias == contentTypeAlias);
|
|
|
|
|
var contentTypes = repository.GetByQuery(query);
|
|
|
|
|
|
|
|
|
|
if (!contentTypes.Any())
|
2012-10-25 18:38:23 -02:00
|
|
|
throw new Exception(string.Format("No ContentType matching the passed in Alias: '{0}' was found", contentTypeAlias));
|
2012-10-10 12:13:23 -02:00
|
|
|
|
|
|
|
|
var contentType = contentTypes.First();
|
|
|
|
|
|
|
|
|
|
if (contentType == null)
|
2012-10-31 08:20:45 -01:00
|
|
|
throw new Exception(string.Format("ContentType matching the passed in Alias: '{0}' was null", contentTypeAlias));
|
2012-10-10 12:13:23 -02:00
|
|
|
|
2012-11-14 11:20:21 -01:00
|
|
|
IContent content = null;
|
|
|
|
|
|
|
|
|
|
var e = new NewEventArgs{Alias = contentTypeAlias, ParentId = parentId};
|
|
|
|
|
if (Creating != null)
|
|
|
|
|
Creating(content, e);
|
|
|
|
|
|
|
|
|
|
if (!e.Cancel)
|
|
|
|
|
{
|
|
|
|
|
content = new Content(parentId, contentType);
|
|
|
|
|
SetUser(content, userId);
|
|
|
|
|
SetWriter(content, userId);
|
|
|
|
|
|
|
|
|
|
if (Created != null)
|
|
|
|
|
Created(content, e);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-05 14:42:21 -01:00
|
|
|
return content;
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Gets an <see cref="IContent"/> object by Id
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="id">Id of the Content to retrieve</param>
|
|
|
|
|
/// <returns><see cref="IContent"/></returns>
|
2012-10-03 12:51:32 -02:00
|
|
|
public IContent GetById(int id)
|
|
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
using(var repository = RepositoryResolver.Current.Factory.CreateContentRepository(_uowProvider.GetUnitOfWork()))
|
|
|
|
|
{
|
|
|
|
|
return repository.Get(id);
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
|
2012-11-13 19:07:43 -01:00
|
|
|
/// <summary>
|
|
|
|
|
/// Gets an <see cref="IContent"/> object by its 'UniqueId'
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="key">Guid key of the Content to retrieve</param>
|
|
|
|
|
/// <returns><see cref="IContent"/></returns>
|
|
|
|
|
public IContent GetById(Guid key)
|
|
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
using(var repository = RepositoryResolver.Current.Factory.CreateContentRepository(_uowProvider.GetUnitOfWork()))
|
|
|
|
|
{
|
|
|
|
|
var query = Query<IContent>.Builder.Where(x => x.Key == key);
|
|
|
|
|
var contents = repository.GetByQuery(query);
|
|
|
|
|
return contents.SingleOrDefault();
|
|
|
|
|
}
|
2012-11-13 19:07:43 -01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-10-24 08:36:45 -02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Gets a collection of <see cref="IContent"/> objects by the Id of the <see cref="IContentType"/>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="id">Id of the <see cref="IContentType"/></param>
|
|
|
|
|
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
|
|
|
|
public IEnumerable<IContent> GetContentOfContentType(int id)
|
|
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
using (var repository = RepositoryResolver.Current.Factory.CreateContentRepository(_uowProvider.GetUnitOfWork()))
|
|
|
|
|
{
|
|
|
|
|
var query = Query<IContent>.Builder.Where(x => x.ContentTypeId == id);
|
|
|
|
|
var contents = repository.GetByQuery(query);
|
2012-10-24 08:36:45 -02:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
return contents;
|
|
|
|
|
}
|
2012-10-24 08:36:45 -02:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Gets a collection of <see cref="IContent"/> objects by Level
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="level">The level to retrieve Content from</param>
|
|
|
|
|
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
2012-10-03 12:51:32 -02:00
|
|
|
public IEnumerable<IContent> GetByLevel(int level)
|
|
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
using (var repository = RepositoryResolver.Current.Factory.CreateContentRepository(_uowProvider.GetUnitOfWork()))
|
|
|
|
|
{
|
|
|
|
|
var query = Query<IContent>.Builder.Where(x => x.Level == level);
|
|
|
|
|
var contents = repository.GetByQuery(query);
|
2012-10-10 12:13:23 -02:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
return contents;
|
|
|
|
|
}
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Gets a collection of <see cref="IContent"/> objects by Parent Id
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="id">Id of the Parent to retrieve Children from</param>
|
|
|
|
|
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
2012-10-03 12:51:32 -02:00
|
|
|
public IEnumerable<IContent> GetChildren(int id)
|
|
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
using(var repository = RepositoryResolver.Current.Factory.CreateContentRepository(_uowProvider.GetUnitOfWork()))
|
|
|
|
|
{
|
|
|
|
|
var query = Query<IContent>.Builder.Where(x => x.ParentId == id);
|
|
|
|
|
var contents = repository.GetByQuery(query);
|
2012-10-10 12:13:23 -02:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
return contents;
|
|
|
|
|
}
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Gets a collection of an <see cref="IContent"/> objects versions by Id
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="id"></param>
|
|
|
|
|
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
2012-10-03 12:51:32 -02:00
|
|
|
public IEnumerable<IContent> GetVersions(int id)
|
|
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
using (var repository = RepositoryResolver.Current.Factory.CreateContentRepository(_uowProvider.GetUnitOfWork()))
|
|
|
|
|
{
|
|
|
|
|
var versions = repository.GetAllVersions(id);
|
|
|
|
|
return versions;
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Gets a collection of <see cref="IContent"/> objects, which reside at the first level / root
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
2012-10-03 12:51:32 -02:00
|
|
|
public IEnumerable<IContent> GetRootContent()
|
|
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
using (var repository = RepositoryResolver.Current.Factory.CreateContentRepository(_uowProvider.GetUnitOfWork()))
|
|
|
|
|
{
|
|
|
|
|
var query = Query<IContent>.Builder.Where(x => x.ParentId == -1);
|
|
|
|
|
var contents = repository.GetByQuery(query);
|
2012-10-10 12:13:23 -02:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
return contents;
|
|
|
|
|
}
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
2012-10-31 15:15:02 -01:00
|
|
|
/// Gets a collection of <see cref="IContent"/> objects, which has an expiration date less than or equal to today.
|
2012-10-10 12:13:23 -02:00
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
2012-10-03 12:51:32 -02:00
|
|
|
public IEnumerable<IContent> GetContentForExpiration()
|
|
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
using (var repository = RepositoryResolver.Current.Factory.CreateContentRepository(_uowProvider.GetUnitOfWork()))
|
|
|
|
|
{
|
|
|
|
|
var query = Query<IContent>.Builder.Where(x => x.Published == true && x.ExpireDate <= DateTime.UtcNow);
|
|
|
|
|
var contents = repository.GetByQuery(query);
|
2012-10-10 12:13:23 -02:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
return contents;
|
|
|
|
|
}
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
2012-10-31 15:15:02 -01:00
|
|
|
/// Gets a collection of <see cref="IContent"/> objects, which has a release date less than or equal to today.
|
2012-10-10 12:13:23 -02:00
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
2012-10-03 12:51:32 -02:00
|
|
|
public IEnumerable<IContent> GetContentForRelease()
|
|
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
using (var repository = RepositoryResolver.Current.Factory.CreateContentRepository(_uowProvider.GetUnitOfWork()))
|
|
|
|
|
{
|
|
|
|
|
var query = Query<IContent>.Builder.Where(x => x.Published == false && x.ReleaseDate <= DateTime.UtcNow);
|
|
|
|
|
var contents = repository.GetByQuery(query);
|
2012-10-10 12:13:23 -02:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
return contents;
|
|
|
|
|
}
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Gets a collection of an <see cref="IContent"/> objects, which resides in the Recycle Bin
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
2012-10-03 12:51:32 -02:00
|
|
|
public IEnumerable<IContent> GetContentInRecycleBin()
|
|
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
using (var repository = RepositoryResolver.Current.Factory.CreateContentRepository(_uowProvider.GetUnitOfWork()))
|
|
|
|
|
{
|
|
|
|
|
var query = Query<IContent>.Builder.Where(x => x.ParentId == -20);
|
|
|
|
|
var contents = repository.GetByQuery(query);
|
2012-10-10 12:13:23 -02:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
return contents;
|
|
|
|
|
}
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Re-Publishes all Content
|
|
|
|
|
/// </summary>
|
2012-11-05 14:42:21 -01:00
|
|
|
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <returns>True if publishing succeeded, otherwise False</returns>
|
2012-11-05 14:42:21 -01:00
|
|
|
public bool RePublishAll(int userId = -1)
|
2012-10-03 12:51:32 -02:00
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
var uow = _uowProvider.GetUnitOfWork();
|
|
|
|
|
using (var repository = RepositoryResolver.Current.Factory.CreateContentRepository(uow))
|
2012-10-10 12:13:23 -02:00
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
var list = new List<IContent>();
|
|
|
|
|
|
|
|
|
|
//Consider creating a Path query instead of recursive method:
|
|
|
|
|
//var query = Query<IContent>.Builder.Where(x => x.Path.StartsWith("-1"));
|
|
|
|
|
|
|
|
|
|
var rootContent = GetRootContent();
|
|
|
|
|
foreach (var content in rootContent)
|
|
|
|
|
{
|
|
|
|
|
if (content.IsValid())
|
|
|
|
|
{
|
|
|
|
|
list.Add(content);
|
|
|
|
|
list.AddRange(GetChildrenDeep(content.Id));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Publish and then update the database with new status
|
|
|
|
|
var published = _publishingStrategy.PublishWithChildren(list, userId);
|
|
|
|
|
if (published)
|
|
|
|
|
{
|
|
|
|
|
//Only loop through content where the Published property has been updated
|
|
|
|
|
foreach (var item in list.Where(x => ((ICanBeDirty)x).IsPropertyDirty("Published")))
|
|
|
|
|
{
|
|
|
|
|
SetWriter(item, userId);
|
|
|
|
|
repository.AddOrUpdate(item);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uow.Commit();
|
|
|
|
|
|
|
|
|
|
//TODO Change this so we can avoid a depencency to the horrible library method / umbraco.content (singleton) class.
|
|
|
|
|
//global::umbraco.library.RefreshContent();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return published;
|
2012-10-10 12:13:23 -02:00
|
|
|
}
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Publishes a single <see cref="IContent"/> object
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="content">The <see cref="IContent"/> to publish</param>
|
2012-11-05 14:42:21 -01:00
|
|
|
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <returns>True if publishing succeeded, otherwise False</returns>
|
2012-11-05 14:42:21 -01:00
|
|
|
public bool Publish(IContent content, int userId = -1)
|
2012-10-03 12:51:32 -02:00
|
|
|
{
|
2012-10-10 12:13:23 -02:00
|
|
|
return SaveAndPublish(content, userId);
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Publishes a <see cref="IContent"/> object and all its children
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="content">The <see cref="IContent"/> to publish along with its children</param>
|
2012-11-05 14:42:21 -01:00
|
|
|
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <returns>True if publishing succeeded, otherwise False</returns>
|
2012-11-05 14:42:21 -01:00
|
|
|
public bool PublishWithChildren(IContent content, int userId = -1)
|
2012-10-03 12:51:32 -02:00
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
var uow = _uowProvider.GetUnitOfWork();
|
|
|
|
|
using (var repository = RepositoryResolver.Current.Factory.CreateContentRepository(uow))
|
2012-10-29 14:28:16 -01:00
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
//Check if parent is published (although not if its a root node) - if parent isn't published this Content cannot be published
|
|
|
|
|
if (content.ParentId != -1 && content.ParentId != -20 && !GetById(content.ParentId).Published)
|
|
|
|
|
{
|
|
|
|
|
LogHelper.Info<ContentService>(
|
|
|
|
|
string.Format("Content '{0}' with Id '{1}' could not be published because its parent is not published.",
|
|
|
|
|
content.Name, content.Id));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Content contains invalid property values and can therefore not be published - fire event?
|
|
|
|
|
if (!content.IsValid())
|
|
|
|
|
{
|
|
|
|
|
LogHelper.Info<ContentService>(
|
|
|
|
|
string.Format("Content '{0}' with Id '{1}' could not be published because of invalid properties.",
|
|
|
|
|
content.Name, content.Id));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Consider creating a Path query instead of recursive method:
|
|
|
|
|
//var query = Query<IContent>.Builder.Where(x => x.Path.StartsWith(content.Path));
|
|
|
|
|
|
|
|
|
|
var list = new List<IContent>();
|
|
|
|
|
list.Add(content);
|
|
|
|
|
list.AddRange(GetChildrenDeep(content.Id));
|
|
|
|
|
|
|
|
|
|
//Publish and then update the database with new status
|
|
|
|
|
var published = _publishingStrategy.PublishWithChildren(list, userId);
|
|
|
|
|
if (published)
|
|
|
|
|
{
|
|
|
|
|
//Only loop through content where the Published property has been updated
|
|
|
|
|
foreach (var item in list.Where(x => ((ICanBeDirty)x).IsPropertyDirty("Published")))
|
|
|
|
|
{
|
|
|
|
|
SetWriter(item, userId);
|
|
|
|
|
repository.AddOrUpdate(item);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uow.Commit();
|
|
|
|
|
|
|
|
|
|
//TODO Change this so we can avoid a depencency to the horrible library method / umbraco.content (singleton) class.
|
|
|
|
|
//TODO Need to investigate if it will also update the cache for children of the Content object
|
|
|
|
|
//global::umbraco.library.UpdateDocumentCache(content.Id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return published;
|
|
|
|
|
}
|
2012-10-10 12:13:23 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// UnPublishes a single <see cref="IContent"/> object
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="content">The <see cref="IContent"/> to publish</param>
|
2012-11-05 14:42:21 -01:00
|
|
|
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <returns>True if unpublishing succeeded, otherwise False</returns>
|
2012-11-05 14:42:21 -01:00
|
|
|
public bool UnPublish(IContent content, int userId = -1)
|
2012-10-10 12:13:23 -02:00
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
var uow = _uowProvider.GetUnitOfWork();
|
|
|
|
|
using(var repository = RepositoryResolver.Current.Factory.CreateContentRepository(uow))
|
|
|
|
|
{
|
|
|
|
|
//Look for children and unpublish them if any exists, otherwise just unpublish the passed in Content.
|
|
|
|
|
var children = GetChildrenDeep(content.Id);
|
|
|
|
|
var hasChildren = children.Any();
|
2012-10-10 12:13:23 -02:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
if (hasChildren)
|
|
|
|
|
children.Add(content);
|
2012-11-01 10:59:32 -01:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
var unpublished = hasChildren
|
|
|
|
|
? _publishingStrategy.UnPublish(children, userId)
|
|
|
|
|
: _publishingStrategy.UnPublish(content, userId);
|
2012-10-29 14:28:16 -01:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
if (unpublished)
|
|
|
|
|
{
|
|
|
|
|
repository.AddOrUpdate(content);
|
2012-11-01 10:59:32 -01:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
if (hasChildren)
|
|
|
|
|
{
|
|
|
|
|
foreach (var child in children)
|
|
|
|
|
{
|
|
|
|
|
SetWriter(child, userId);
|
|
|
|
|
repository.AddOrUpdate(child);
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-11-01 10:59:32 -01:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
uow.Commit();
|
2012-10-29 14:28:16 -01:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
//TODO Change this so we can avoid a depencency to the horrible library method / umbraco.content class.
|
|
|
|
|
//global::umbraco.library.UnPublishSingleNode(content.Id);
|
|
|
|
|
}
|
2012-10-10 12:13:23 -02:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
return unpublished;
|
|
|
|
|
}
|
2012-10-10 12:13:23 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets a flat list of decendents of content from parent id
|
|
|
|
|
/// </summary>
|
2012-10-29 14:28:16 -01:00
|
|
|
/// <remarks>
|
|
|
|
|
/// Only contains valid <see cref="IContent"/> objects, which means
|
|
|
|
|
/// that everything in the returned list can be published.
|
|
|
|
|
/// If an invalid <see cref="IContent"/> object is found it will not
|
|
|
|
|
/// be added to the list neither will its children.
|
|
|
|
|
/// </remarks>
|
|
|
|
|
/// <param name="parentId">Id of the parent to retrieve children from</param>
|
|
|
|
|
/// <returns>A list of valid <see cref="IContent"/> that can be published</returns>
|
2012-10-10 12:13:23 -02:00
|
|
|
private List<IContent> GetChildrenDeep(int parentId)
|
|
|
|
|
{
|
|
|
|
|
var list = new List<IContent>();
|
|
|
|
|
var children = GetChildren(parentId);
|
|
|
|
|
foreach (var child in children)
|
|
|
|
|
{
|
2012-10-29 14:28:16 -01:00
|
|
|
if (child.IsValid())
|
|
|
|
|
{
|
|
|
|
|
list.Add(child);
|
|
|
|
|
list.AddRange(GetChildrenDeep(child.Id));
|
|
|
|
|
}
|
2012-10-10 12:13:23 -02:00
|
|
|
}
|
|
|
|
|
return list;
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Saves and Publishes a single <see cref="IContent"/> object
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="content">The <see cref="IContent"/> to save and publish</param>
|
2012-11-05 14:42:21 -01:00
|
|
|
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <returns>True if publishing succeeded, otherwise False</returns>
|
2012-11-05 14:42:21 -01:00
|
|
|
public bool SaveAndPublish(IContent content, int userId = -1)
|
2012-12-11 12:03:36 +05:00
|
|
|
{
|
|
|
|
|
var uow = _uowProvider.GetUnitOfWork();
|
|
|
|
|
using (var repository = RepositoryResolver.Current.Factory.CreateContentRepository(uow))
|
|
|
|
|
{
|
2012-12-11 22:56:34 +05:00
|
|
|
var e = new SaveEventArgs();
|
2012-12-11 12:03:36 +05:00
|
|
|
if (Saving != null)
|
|
|
|
|
Saving(content, e);
|
|
|
|
|
|
|
|
|
|
if (!e.Cancel)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
//Check if parent is published (although not if its a root node) - if parent isn't published this Content cannot be published
|
|
|
|
|
if (content.ParentId != -1 && content.ParentId != -20 && GetById(content.ParentId).Published == false)
|
|
|
|
|
{
|
|
|
|
|
LogHelper.Info<ContentService>(
|
|
|
|
|
string.Format(
|
|
|
|
|
"Content '{0}' with Id '{1}' could not be published because its parent is not published.",
|
|
|
|
|
content.Name, content.Id));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Content contains invalid property values and can therefore not be published - fire event?
|
|
|
|
|
if (!content.IsValid())
|
|
|
|
|
{
|
|
|
|
|
LogHelper.Info<ContentService>(
|
|
|
|
|
string.Format(
|
|
|
|
|
"Content '{0}' with Id '{1}' could not be published because of invalid properties.",
|
|
|
|
|
content.Name, content.Id));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Publish and then update the database with new status
|
|
|
|
|
bool published = _publishingStrategy.Publish(content, userId);
|
|
|
|
|
if (published)
|
|
|
|
|
{
|
|
|
|
|
SetWriter(content, userId);
|
|
|
|
|
repository.AddOrUpdate(content);
|
|
|
|
|
uow.Commit();
|
|
|
|
|
|
|
|
|
|
//TODO Change this so we can avoid a depencency to the horrible library method / umbraco.content (singleton) class.
|
|
|
|
|
//global::umbraco.library.UpdateDocumentCache(content.Id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Saved != null)
|
|
|
|
|
Saved(content, e);
|
|
|
|
|
|
|
|
|
|
return published;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Saves a single <see cref="IContent"/> object
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="content">The <see cref="IContent"/> to save</param>
|
2012-11-05 14:42:21 -01:00
|
|
|
/// <param name="userId">Optional Id of the User saving the Content</param>
|
|
|
|
|
public void Save(IContent content, int userId = -1)
|
2012-10-03 12:51:32 -02:00
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
var uow = _uowProvider.GetUnitOfWork();
|
|
|
|
|
using (var repository = RepositoryResolver.Current.Factory.CreateContentRepository(uow))
|
|
|
|
|
{
|
2012-12-11 22:56:34 +05:00
|
|
|
var e = new SaveEventArgs();
|
2012-12-11 12:03:36 +05:00
|
|
|
if (Saving != null)
|
|
|
|
|
Saving(content, e);
|
2012-11-05 14:42:21 -01:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
if (!e.Cancel)
|
|
|
|
|
{
|
2012-11-05 14:42:21 -01:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
SetWriter(content, userId);
|
|
|
|
|
content.ChangePublishedState(false);
|
|
|
|
|
repository.AddOrUpdate(content);
|
|
|
|
|
uow.Commit();
|
2012-11-14 11:20:21 -01:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
if (Saved != null)
|
|
|
|
|
Saved(content, e);
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
2012-11-13 14:30:05 -01:00
|
|
|
/// Saves a collection of <see cref="IContent"/> objects.
|
2012-10-10 12:13:23 -02:00
|
|
|
/// </summary>
|
2012-11-13 14:30:05 -01:00
|
|
|
/// <remarks>
|
|
|
|
|
/// If the collection of content contains new objects that references eachother by Id or ParentId,
|
|
|
|
|
/// then use the overload Save method with a collection of Lazy <see cref="IContent"/>.
|
|
|
|
|
/// </remarks>
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <param name="contents">Collection of <see cref="IContent"/> to save</param>
|
2012-11-05 14:42:21 -01:00
|
|
|
/// <param name="userId">Optional Id of the User saving the Content</param>
|
|
|
|
|
public void Save(IEnumerable<IContent> contents, int userId = -1)
|
2012-11-13 14:30:05 -01:00
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
var uow = _uowProvider.GetUnitOfWork();
|
|
|
|
|
using (var repository = RepositoryResolver.Current.Factory.CreateContentRepository(uow))
|
2012-11-13 14:30:05 -01:00
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
var containsNew = contents.Any(x => x.HasIdentity == false);
|
|
|
|
|
|
2012-12-11 22:56:34 +05:00
|
|
|
var e = new SaveEventArgs();
|
2012-12-11 12:03:36 +05:00
|
|
|
if (Saving != null)
|
|
|
|
|
Saving(contents, e);
|
|
|
|
|
|
|
|
|
|
if (!e.Cancel)
|
|
|
|
|
{
|
|
|
|
|
if (containsNew)
|
|
|
|
|
{
|
|
|
|
|
foreach (var content in contents)
|
|
|
|
|
{
|
|
|
|
|
SetWriter(content, userId);
|
|
|
|
|
content.ChangePublishedState(false);
|
|
|
|
|
repository.AddOrUpdate(content);
|
|
|
|
|
uow.Commit();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
foreach (var content in contents)
|
|
|
|
|
{
|
|
|
|
|
if (Saving != null)
|
|
|
|
|
Saving(content, e);
|
|
|
|
|
|
|
|
|
|
SetWriter(content, userId);
|
|
|
|
|
repository.AddOrUpdate(content);
|
|
|
|
|
}
|
|
|
|
|
uow.Commit();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Saved != null)
|
|
|
|
|
Saved(contents, e);
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-11-13 14:30:05 -01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Saves a collection of lazy loaded <see cref="IContent"/> objects.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
/// This method ensures that Content is saved lazily, so a new graph of <see cref="IContent"/>
|
2012-11-23 19:58:19 -01:00
|
|
|
/// objects can be saved in bulk. But note that objects are saved one at a time to ensure Ids.
|
2012-11-13 14:30:05 -01:00
|
|
|
/// </remarks>
|
|
|
|
|
/// <param name="contents">Collection of Lazy <see cref="IContent"/> to save</param>
|
|
|
|
|
/// <param name="userId">Optional Id of the User saving the Content</param>
|
|
|
|
|
public void Save(IEnumerable<Lazy<IContent>> contents, int userId = -1)
|
2012-10-03 12:51:32 -02:00
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
var uow = _uowProvider.GetUnitOfWork();
|
|
|
|
|
using (var repository = RepositoryResolver.Current.Factory.CreateContentRepository(uow))
|
|
|
|
|
{
|
2012-12-11 22:56:34 +05:00
|
|
|
var e = new SaveEventArgs();
|
2012-12-11 12:03:36 +05:00
|
|
|
if (Saving != null)
|
|
|
|
|
Saving(contents, e);
|
|
|
|
|
|
|
|
|
|
if (!e.Cancel)
|
|
|
|
|
{
|
|
|
|
|
foreach (var content in contents)
|
|
|
|
|
{
|
|
|
|
|
SetWriter(content.Value, userId);
|
|
|
|
|
content.Value.ChangePublishedState(false);
|
|
|
|
|
repository.AddOrUpdate(content.Value);
|
|
|
|
|
uow.Commit();
|
|
|
|
|
}
|
|
|
|
|
if (Saved != null)
|
|
|
|
|
Saved(contents, e);
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Deletes all content of specified type. All children of deleted content is moved to Recycle Bin.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <remarks>This needs extra care and attention as its potentially a dangerous and extensive operation</remarks>
|
|
|
|
|
/// <param name="contentTypeId">Id of the <see cref="IContentType"/></param>
|
2012-10-03 12:51:32 -02:00
|
|
|
public void DeleteContentOfType(int contentTypeId)
|
|
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
var uow = _uowProvider.GetUnitOfWork();
|
|
|
|
|
using (var repository = RepositoryResolver.Current.Factory.CreateContentRepository(uow))
|
|
|
|
|
{
|
|
|
|
|
//NOTE What about content that has the contenttype as part of its composition?
|
|
|
|
|
var query = Query<IContent>.Builder.Where(x => x.ContentTypeId == contentTypeId);
|
|
|
|
|
var contents = repository.GetByQuery(query);
|
2012-10-10 12:13:23 -02:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
var e = new DeleteEventArgs { Id = contentTypeId };
|
|
|
|
|
if (Deleting != null)
|
|
|
|
|
Deleting(contents, e);
|
2012-11-14 11:20:21 -01:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
if (!e.Cancel)
|
|
|
|
|
{
|
|
|
|
|
foreach (var content in contents)
|
|
|
|
|
{
|
|
|
|
|
((Content)content).ChangeTrashedState(true);
|
|
|
|
|
repository.AddOrUpdate(content);
|
|
|
|
|
}
|
2012-10-10 12:13:23 -02:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
uow.Commit();
|
2012-11-14 11:20:21 -01:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
if (Deleted != null)
|
|
|
|
|
Deleted(contents, e);
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Permanently deletes an <see cref="IContent"/> object
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <remarks>Please note that this method will completely remove the Content from the database</remarks>
|
|
|
|
|
/// <param name="content">The <see cref="IContent"/> to delete</param>
|
2012-11-05 14:42:21 -01:00
|
|
|
/// <param name="userId">Optional Id of the User deleting the Content</param>
|
|
|
|
|
public void Delete(IContent content, int userId = -1)
|
2012-10-03 12:51:32 -02:00
|
|
|
{
|
2012-10-24 08:36:45 -02:00
|
|
|
//TODO Ensure that content is unpublished when deleted
|
2012-10-10 12:13:23 -02:00
|
|
|
//TODO This method should handle/react to errors when there is a constraint issue with the content being deleted
|
2012-10-24 08:36:45 -02:00
|
|
|
//TODO Children should either be deleted or moved to the recycle bin
|
2012-11-14 11:20:21 -01:00
|
|
|
|
|
|
|
|
var e = new DeleteEventArgs { Id = content.Id };
|
|
|
|
|
if (Deleting != null)
|
|
|
|
|
Deleting(content, e);
|
|
|
|
|
|
|
|
|
|
if (!e.Cancel)
|
|
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
var uow = _uowProvider.GetUnitOfWork();
|
|
|
|
|
using (var repository = RepositoryResolver.Current.Factory.CreateContentRepository(uow))
|
|
|
|
|
{
|
|
|
|
|
SetWriter(content, userId);
|
|
|
|
|
repository.Delete(content);
|
|
|
|
|
uow.Commit();
|
2012-11-14 11:20:21 -01:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
if (Deleted != null)
|
|
|
|
|
Deleted(content, e);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-14 11:20:21 -01:00
|
|
|
}
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
|
2012-11-11 14:55:48 -01:00
|
|
|
/// <summary>
|
|
|
|
|
/// Permanently deletes versions from an <see cref="IContent"/> object prior to a specific date.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="content">Id of the <see cref="IContent"/> object to delete versions from</param>
|
|
|
|
|
/// <param name="versionDate">Latest version date</param>
|
|
|
|
|
/// <param name="userId">Optional Id of the User deleting versions of a Content object</param>
|
|
|
|
|
public void Delete(IContent content, DateTime versionDate, int userId = -1)
|
|
|
|
|
{
|
|
|
|
|
Delete(content.Id, versionDate, userId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2012-11-11 18:07:52 -01:00
|
|
|
/// Permanently deletes specific version(s) from an <see cref="IContent"/> object.
|
2012-11-11 14:55:48 -01:00
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="content">Id of the <see cref="IContent"/> object to delete a version from</param>
|
|
|
|
|
/// <param name="versionId">Id of the version to delete</param>
|
2012-11-11 18:07:52 -01:00
|
|
|
/// <param name="deletePriorVersions">Boolean indicating whether to delete versions prior to the versionId</param>
|
2012-11-11 14:55:48 -01:00
|
|
|
/// <param name="userId">Optional Id of the User deleting versions of a Content object</param>
|
2012-11-11 18:07:52 -01:00
|
|
|
public void Delete(IContent content, Guid versionId, bool deletePriorVersions, int userId = -1)
|
2012-11-11 14:55:48 -01:00
|
|
|
{
|
2012-11-11 18:07:52 -01:00
|
|
|
Delete(content.Id, versionId, deletePriorVersions, userId);
|
2012-11-11 14:55:48 -01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Permanently deletes versions from an <see cref="IContent"/> object prior to a specific date.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="id">Id of the <see cref="IContent"/> object to delete versions from</param>
|
|
|
|
|
/// <param name="versionDate">Latest version date</param>
|
|
|
|
|
/// <param name="userId">Optional Id of the User deleting versions of a Content object</param>
|
|
|
|
|
public void Delete(int id, DateTime versionDate, int userId = -1)
|
|
|
|
|
{
|
2012-11-14 11:20:21 -01:00
|
|
|
var e = new DeleteEventArgs { Id = id };
|
|
|
|
|
if (Deleting != null)
|
|
|
|
|
Deleting(versionDate, e);
|
|
|
|
|
|
|
|
|
|
if (!e.Cancel)
|
|
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
using (var repository = RepositoryResolver.Current.Factory.CreateContentRepository(_uowProvider.GetUnitOfWork()))
|
|
|
|
|
{
|
|
|
|
|
repository.Delete(id, versionDate);
|
2012-11-14 11:20:21 -01:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
if (Deleted != null)
|
|
|
|
|
Deleted(versionDate, e);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-14 11:20:21 -01:00
|
|
|
}
|
2012-11-11 14:55:48 -01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2012-11-11 18:07:52 -01:00
|
|
|
/// Permanently deletes specific version(s) from an <see cref="IContent"/> object.
|
2012-11-11 14:55:48 -01:00
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="id">Id of the <see cref="IContent"/> object to delete a version from</param>
|
|
|
|
|
/// <param name="versionId">Id of the version to delete</param>
|
2012-11-11 18:07:52 -01:00
|
|
|
/// <param name="deletePriorVersions">Boolean indicating whether to delete versions prior to the versionId</param>
|
2012-11-11 14:55:48 -01:00
|
|
|
/// <param name="userId">Optional Id of the User deleting versions of a Content object</param>
|
2012-11-11 18:07:52 -01:00
|
|
|
public void Delete(int id, Guid versionId, bool deletePriorVersions, int userId = -1)
|
2012-11-11 14:55:48 -01:00
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
using (var repository = RepositoryResolver.Current.Factory.CreateContentRepository(_uowProvider.GetUnitOfWork()))
|
2012-11-11 18:07:52 -01:00
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
if (deletePriorVersions)
|
|
|
|
|
{
|
|
|
|
|
var content = repository.GetByVersion(id, versionId);
|
|
|
|
|
Delete(id, content.UpdateDate, userId);
|
|
|
|
|
}
|
2012-11-11 18:07:52 -01:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
var e = new DeleteEventArgs { Id = id };
|
|
|
|
|
if (Deleting != null)
|
|
|
|
|
Deleting(versionId, e);
|
2012-11-14 11:20:21 -01:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
if (!e.Cancel)
|
|
|
|
|
{
|
|
|
|
|
repository.Delete(id, versionId);
|
2012-11-14 11:20:21 -01:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
if (Deleted != null)
|
|
|
|
|
Deleted(versionId, e);
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-11-11 14:55:48 -01:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Deletes an <see cref="IContent"/> object by moving it to the Recycle Bin
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <remarks>Move an item to the Recycle Bin will result in the item being unpublished</remarks>
|
|
|
|
|
/// <param name="content">The <see cref="IContent"/> to delete</param>
|
2012-11-05 14:42:21 -01:00
|
|
|
/// <param name="userId">Optional Id of the User deleting the Content</param>
|
|
|
|
|
public void MoveToRecycleBin(IContent content, int userId = -1)
|
2012-10-03 12:51:32 -02:00
|
|
|
{
|
2012-10-24 08:36:45 -02:00
|
|
|
//TODO If content item has children those should also be moved to the recycle bin
|
|
|
|
|
//TODO Unpublish deleted content + children
|
2012-12-11 12:03:36 +05:00
|
|
|
var uow = _uowProvider.GetUnitOfWork();
|
|
|
|
|
using (var repository = RepositoryResolver.Current.Factory.CreateContentRepository(uow))
|
|
|
|
|
{
|
|
|
|
|
SetWriter(content, userId);
|
|
|
|
|
content.ChangeTrashedState(true);
|
|
|
|
|
repository.AddOrUpdate(content);
|
|
|
|
|
uow.Commit();
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
2012-10-31 08:20:45 -01:00
|
|
|
/// Moves an <see cref="IContent"/> object to a new location by changing its parent id.
|
2012-10-10 12:13:23 -02:00
|
|
|
/// </summary>
|
2012-10-31 08:20:45 -01:00
|
|
|
/// <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>
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <param name="content">The <see cref="IContent"/> to move</param>
|
|
|
|
|
/// <param name="parentId">Id of the Content's new Parent</param>
|
2012-11-05 14:42:21 -01:00
|
|
|
/// <param name="userId">Optional Id of the User moving the Content</param>
|
|
|
|
|
public void Move(IContent content, int parentId, int userId = -1)
|
2012-10-03 12:51:32 -02:00
|
|
|
{
|
2012-11-14 11:20:21 -01:00
|
|
|
var e = new MoveEventArgs { ParentId = parentId };
|
|
|
|
|
if (Moving != null)
|
|
|
|
|
Moving(content, e);
|
2012-11-05 14:42:21 -01:00
|
|
|
|
2012-11-14 11:20:21 -01:00
|
|
|
if (!e.Cancel)
|
2012-10-31 15:15:02 -01:00
|
|
|
{
|
2012-11-14 11:20:21 -01:00
|
|
|
SetWriter(content, userId);
|
2012-10-31 15:15:02 -01:00
|
|
|
|
2012-11-14 11:20:21 -01:00
|
|
|
//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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//If Content is published, it should be (re)published from its new location
|
|
|
|
|
if (content.Published)
|
|
|
|
|
{
|
|
|
|
|
SaveAndPublish(content, userId);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Save(content, userId);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-14 13:27:34 -01:00
|
|
|
if(Moved != null)
|
|
|
|
|
Moved(content, e);
|
2012-10-31 08:20:45 -01:00
|
|
|
}
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
|
2012-10-24 08:36:45 -02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Empties the Recycle Bin by deleting all <see cref="IContent"/> that resides in the bin
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void EmptyRecycleBin()
|
|
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
var uow = _uowProvider.GetUnitOfWork();
|
|
|
|
|
using (var repository = RepositoryResolver.Current.Factory.CreateContentRepository(uow))
|
2012-10-24 08:36:45 -02:00
|
|
|
{
|
2012-12-11 12:03:36 +05:00
|
|
|
var query = Query<IContent>.Builder.Where(x => x.ParentId == -20);
|
|
|
|
|
var contents = repository.GetByQuery(query);
|
|
|
|
|
|
|
|
|
|
foreach (var content in contents)
|
|
|
|
|
{
|
|
|
|
|
repository.Delete(content);
|
|
|
|
|
}
|
|
|
|
|
uow.Commit();
|
|
|
|
|
}
|
2012-10-24 08:36:45 -02:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Copies an <see cref="IContent"/> object by creating a new Content object of the same type and copies all data from the current
|
|
|
|
|
/// to the new copy which is returned.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="content">The <see cref="IContent"/> to copy</param>
|
|
|
|
|
/// <param name="parentId">Id of the Content's new Parent</param>
|
2012-11-05 14:42:21 -01:00
|
|
|
/// <param name="userId">Optional Id of the User copying the Content</param>
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <returns>The newly created <see cref="IContent"/> object</returns>
|
2012-11-05 14:42:21 -01:00
|
|
|
public IContent Copy(IContent content, int parentId, int userId = -1)
|
2012-10-03 12:51:32 -02:00
|
|
|
{
|
2012-11-14 11:20:21 -01:00
|
|
|
var e = new CopyEventArgs{ParentId = parentId};
|
|
|
|
|
if (Copying != null)
|
|
|
|
|
Copying(content, e);
|
2012-10-10 12:13:23 -02:00
|
|
|
|
2012-11-14 11:20:21 -01:00
|
|
|
IContent copy = null;
|
2012-10-10 12:13:23 -02:00
|
|
|
|
2012-11-14 11:20:21 -01:00
|
|
|
if (!e.Cancel)
|
|
|
|
|
{
|
|
|
|
|
copy = ((Content) content).Clone();
|
|
|
|
|
copy.ParentId = parentId;
|
|
|
|
|
copy.Name = copy.Name + " (1)";
|
|
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
var uow = _uowProvider.GetUnitOfWork();
|
|
|
|
|
using (var repository = RepositoryResolver.Current.Factory.CreateContentRepository(uow))
|
|
|
|
|
{
|
|
|
|
|
SetWriter(content, userId);
|
2012-11-14 11:20:21 -01:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
repository.AddOrUpdate(copy);
|
|
|
|
|
uow.Commit();
|
|
|
|
|
}
|
2012-11-14 11:20:21 -01:00
|
|
|
}
|
|
|
|
|
|
2012-11-14 13:27:34 -01:00
|
|
|
if(Copied != null)
|
|
|
|
|
Copied(copy, e);
|
2012-11-05 14:42:21 -01:00
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
return copy;
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Sends an <see cref="IContent"/> to Publication, which executes handlers and events for the 'Send to Publication' action.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="content">The <see cref="IContent"/> to send to publication</param>
|
2012-11-05 14:42:21 -01:00
|
|
|
/// <param name="userId">Optional Id of the User issueing the send to publication</param>
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <returns>True if sending publication was succesfull otherwise false</returns>
|
2012-11-05 14:42:21 -01:00
|
|
|
public bool SendToPublication(IContent content, int userId = -1)
|
2012-10-03 12:51:32 -02:00
|
|
|
{
|
2012-10-10 12:13:23 -02:00
|
|
|
//TODO Implement something similar to this
|
2012-11-14 11:20:21 -01:00
|
|
|
var e = new SendToPublishEventArgs();
|
|
|
|
|
|
|
|
|
|
if (SendingToPublish != null)
|
|
|
|
|
SendingToPublish(content, e);
|
|
|
|
|
|
|
|
|
|
if (!e.Cancel)
|
|
|
|
|
{
|
|
|
|
|
// Do some stuff here..
|
|
|
|
|
|
|
|
|
|
if (SentToPublish != null)
|
|
|
|
|
SentToPublish(content, e);
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/*SendToPublishEventArgs e = new SendToPublishEventArgs();
|
|
|
|
|
FireBeforeSendToPublish(e);
|
|
|
|
|
if (!e.Cancel)
|
|
|
|
|
{
|
|
|
|
|
global::umbraco.BusinessLogic.Actions.Action.RunActionHandlers(content, ActionToPublish.Instance);
|
|
|
|
|
|
|
|
|
|
FireAfterSendToPublish(e);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;*/
|
|
|
|
|
return false;
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Rollback an <see cref="IContent"/> object to a previous version.
|
|
|
|
|
/// This will create a new version, which is a copy of all the old data.
|
|
|
|
|
/// </summary>
|
2012-10-31 15:15:02 -01:00
|
|
|
/// <remarks>
|
|
|
|
|
/// The way data is stored actually only allows us to rollback on properties
|
|
|
|
|
/// and not data like Name and Alias of the Content.
|
|
|
|
|
/// </remarks>
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <param name="id">Id of the <see cref="IContent"/>being rolled back</param>
|
|
|
|
|
/// <param name="versionId">Id of the version to rollback to</param>
|
2012-11-05 14:42:21 -01:00
|
|
|
/// <param name="userId">Optional Id of the User issueing the rollback of the Content</param>
|
2012-10-10 12:13:23 -02:00
|
|
|
/// <returns>The newly created <see cref="IContent"/> object</returns>
|
2012-11-05 14:42:21 -01:00
|
|
|
public IContent Rollback(int id, Guid versionId, int userId = -1)
|
2012-10-03 12:51:32 -02:00
|
|
|
{
|
2012-11-14 11:20:21 -01:00
|
|
|
var e = new RollbackEventArgs();
|
|
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
var uow = _uowProvider.GetUnitOfWork();
|
|
|
|
|
using (var repository = RepositoryResolver.Current.Factory.CreateContentRepository(uow))
|
|
|
|
|
{
|
|
|
|
|
var content = repository.GetByVersion(id, versionId);
|
2012-11-05 14:42:21 -01:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
if (Rollingback != null)
|
|
|
|
|
Rollingback(content, e);
|
2012-11-14 11:20:21 -01:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
if (!e.Cancel)
|
|
|
|
|
{
|
|
|
|
|
SetUser(content, userId);
|
|
|
|
|
SetWriter(content, userId);
|
2012-11-14 11:20:21 -01:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
repository.AddOrUpdate(content);
|
|
|
|
|
uow.Commit();
|
2012-11-14 11:20:21 -01:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
if (Rolledback != null)
|
|
|
|
|
Rolledback(content, e);
|
|
|
|
|
}
|
2012-10-10 12:13:23 -02:00
|
|
|
|
2012-12-11 12:03:36 +05:00
|
|
|
return content;
|
|
|
|
|
}
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
2012-11-05 14:42:21 -01:00
|
|
|
|
2012-11-12 08:39:29 -01:00
|
|
|
/// <summary>
|
|
|
|
|
/// Internal method to set the HttpContextBase for testing.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="httpContext"><see cref="HttpContextBase"/></param>
|
|
|
|
|
internal void SetHttpContext(HttpContextBase httpContext)
|
|
|
|
|
{
|
|
|
|
|
_httpContext = httpContext;
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-05 14:42:21 -01:00
|
|
|
/// <summary>
|
|
|
|
|
/// Updates a content object with the User (id), who created the content.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="content"><see cref="IContent"/> object to update</param>
|
|
|
|
|
/// <param name="userId">Optional Id of the User</param>
|
|
|
|
|
private void SetUser(IContent content, int userId)
|
|
|
|
|
{
|
|
|
|
|
if(userId > -1)
|
|
|
|
|
{
|
|
|
|
|
//If a user id was passed in we use that
|
2012-11-11 06:53:02 -01:00
|
|
|
content.CreatorId = userId;
|
2012-11-05 14:42:21 -01:00
|
|
|
}
|
2012-11-13 19:07:43 -01:00
|
|
|
else if (UserServiceOrContext())
|
2012-11-12 08:39:29 -01:00
|
|
|
{
|
|
|
|
|
var profile = _httpContext == null
|
|
|
|
|
? _userService.GetCurrentBackOfficeUser()
|
|
|
|
|
: _userService.GetCurrentBackOfficeUser(_httpContext);
|
|
|
|
|
content.CreatorId = profile.Id.SafeCast<int>();
|
|
|
|
|
}
|
2012-11-05 14:42:21 -01:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//Otherwise we default to Admin user, which should always exist (almost always)
|
2012-11-11 06:53:02 -01:00
|
|
|
content.CreatorId = 0;
|
2012-11-05 14:42:21 -01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Updates a content object with a Writer (user id), who updated the content.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="content"><see cref="IContent"/> object to update</param>
|
|
|
|
|
/// <param name="userId">Optional Id of the Writer</param>
|
|
|
|
|
private void SetWriter(IContent content, int userId)
|
|
|
|
|
{
|
|
|
|
|
if (userId > -1)
|
|
|
|
|
{
|
|
|
|
|
//If a user id was passed in we use that
|
2012-11-11 06:53:02 -01:00
|
|
|
content.WriterId = userId;
|
2012-11-05 14:42:21 -01:00
|
|
|
}
|
2012-11-13 19:07:43 -01:00
|
|
|
else if (UserServiceOrContext())
|
2012-11-12 08:39:29 -01:00
|
|
|
{
|
|
|
|
|
var profile = _httpContext == null
|
|
|
|
|
? _userService.GetCurrentBackOfficeUser()
|
|
|
|
|
: _userService.GetCurrentBackOfficeUser(_httpContext);
|
|
|
|
|
content.WriterId = profile.Id.SafeCast<int>();
|
|
|
|
|
}
|
2012-11-05 14:42:21 -01:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//Otherwise we default to Admin user, which should always exist (almost always)
|
2012-11-11 06:53:02 -01:00
|
|
|
content.WriterId = 0;
|
2012-11-05 14:42:21 -01:00
|
|
|
}
|
|
|
|
|
}
|
2012-11-11 06:53:02 -01:00
|
|
|
|
2012-11-13 19:07:43 -01:00
|
|
|
private bool UserServiceOrContext()
|
|
|
|
|
{
|
|
|
|
|
return _userService != null && (HttpContext.Current != null || _httpContext != null);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-14 11:20:21 -01:00
|
|
|
#region Event Handlers
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Occurs before Delete
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static event EventHandler<DeleteEventArgs> Deleting;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Occurs after Delete
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static event EventHandler<DeleteEventArgs> Deleted;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Occurs before Save
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static event EventHandler<SaveEventArgs> Saving;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Occurs after Save
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static event EventHandler<SaveEventArgs> Saved;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Occurs before Create
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static event EventHandler<NewEventArgs> Creating;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Occurs after Create
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static event EventHandler<NewEventArgs> Created;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Occurs before Copy
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static event EventHandler<CopyEventArgs> Copying;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Occurs after Copy
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static event EventHandler<CopyEventArgs> Copied;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Occurs before Move
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static event EventHandler<MoveEventArgs> Moving;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Occurs after Move
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static event EventHandler<MoveEventArgs> Moved;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Occurs before Rollback
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static event EventHandler<RollbackEventArgs> Rollingback;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Occurs after Rollback
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static event EventHandler<RollbackEventArgs> Rolledback;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Occurs before Send to Publish
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static event EventHandler<SendToPublishEventArgs> SendingToPublish;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Occurs after Send to Publish
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static event EventHandler<SendToPublishEventArgs> SentToPublish;
|
|
|
|
|
#endregion
|
2012-10-03 12:51:32 -02:00
|
|
|
}
|
|
|
|
|
}
|