Adding publish date, version-specific create/modify/publish dates, and unpublish method on content manager

--HG--
extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4045209
This commit is contained in:
loudej
2010-01-10 11:18:28 +00:00
parent a4fcbb482c
commit 864dd42a08
30 changed files with 456 additions and 136 deletions

View File

@@ -3,8 +3,10 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Autofac.Builder; using Autofac.Builder;
using JetBrains.Annotations;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
using Orchard.ContentManagement.Aspects;
using Orchard.Core.Common.Models; using Orchard.Core.Common.Models;
using Orchard.Core.Common.Providers; using Orchard.Core.Common.Providers;
using Orchard.Core.Common.Records; using Orchard.Core.Common.Records;
@@ -37,16 +39,25 @@ namespace Orchard.Core.Tests.Common.Providers {
protected override IEnumerable<Type> DatabaseTypes { protected override IEnumerable<Type> DatabaseTypes {
get { get {
return new[] { typeof(ContentTypeRecord), typeof(ContentItemRecord), typeof(ContentItemVersionRecord), typeof(CommonRecord) }; return new[] {
typeof(ContentTypeRecord),
typeof(ContentItemRecord),
typeof(ContentItemVersionRecord),
typeof(CommonRecord),
typeof(CommonVersionRecord),
};
} }
} }
[UsedImplicitly]
class TestHandler : ContentHandler { class TestHandler : ContentHandler {
public TestHandler() { public TestHandler() {
Filters.Add(new ActivatingFilter<CommonAspect>("test-item")); Filters.Add(new ActivatingFilter<CommonAspect>("test-item"));
Filters.Add(new ActivatingFilter<ContentPart<CommonVersionRecord>>("test-item"));
Filters.Add(new ActivatingFilter<TestUser>("user")); Filters.Add(new ActivatingFilter<TestUser>("user"));
} }
} }
class TestUser : ContentPart, IUser { class TestUser : ContentPart, IUser {
public int Id { get { return 6655321; } } public int Id { get { return 6655321; } }
public string UserName {get { return "x"; }} public string UserName {get { return "x"; }}
@@ -76,5 +87,107 @@ namespace Orchard.Core.Tests.Common.Providers {
Assert.That(item.Record.OwnerId, Is.EqualTo(6655321)); Assert.That(item.Record.OwnerId, Is.EqualTo(6655321));
} }
[Test]
public void PublishingShouldSetPublishUtc() {
var contentManager = _container.Resolve<IContentManager>();
var createUtc = _clock.UtcNow;
var item = contentManager.Create<ICommonAspect>("test-item", VersionOptions.Draft, init => { });
Assert.That(item.CreatedUtc, Is.EqualTo(createUtc));
Assert.That(item.PublishedUtc, Is.Null);
_clock.Advance(TimeSpan.FromMinutes(1));
var publishUtc = _clock.UtcNow;
contentManager.Publish(item.ContentItem);
Assert.That(item.CreatedUtc, Is.EqualTo(createUtc));
Assert.That(item.PublishedUtc, Is.EqualTo(publishUtc));
}
[Test]
public void VersioningItemShouldCreatedAndPublishedUtcValuesPerVersion() {
var contentManager = _container.Resolve<IContentManager>();
var createUtc = _clock.UtcNow;
var item1 = contentManager.Create<ICommonAspect>("test-item", VersionOptions.Draft, init => { });
Assert.That(item1.CreatedUtc, Is.EqualTo(createUtc));
Assert.That(item1.PublishedUtc, Is.Null);
_clock.Advance(TimeSpan.FromMinutes(1));
var publish1Utc = _clock.UtcNow;
contentManager.Publish(item1.ContentItem);
// db records need to be updated before demanding draft as item2 below
_session.Flush();
_clock.Advance(TimeSpan.FromMinutes(1));
var draftUtc = _clock.UtcNow;
var item2 = contentManager.GetDraftRequired<ICommonAspect>(item1.ContentItem.Id);
_clock.Advance(TimeSpan.FromMinutes(1));
var publish2Utc = _clock.UtcNow;
contentManager.Publish(item2.ContentItem);
// both instances non-versioned dates show it was created upfront
Assert.That(item1.CreatedUtc, Is.EqualTo(createUtc));
Assert.That(item2.CreatedUtc, Is.EqualTo(createUtc));
// both instances non-versioned dates show the most recent publish
Assert.That(item1.PublishedUtc, Is.EqualTo(publish2Utc));
Assert.That(item2.PublishedUtc, Is.EqualTo(publish2Utc));
// version1 versioned dates show create was upfront and publish was oldest
Assert.That(item1.VersionCreatedUtc, Is.EqualTo(createUtc));
Assert.That(item1.VersionPublishedUtc, Is.EqualTo(publish1Utc));
// version2 versioned dates show create was midway and publish was most recent
Assert.That(item2.VersionCreatedUtc, Is.EqualTo(draftUtc));
Assert.That(item2.VersionPublishedUtc, Is.EqualTo(publish2Utc));
}
[Test]
public void UnpublishShouldClearFlagButLeaveMostrecentPublishDatesIntact() {
var contentManager = _container.Resolve<IContentManager>();
var createUtc = _clock.UtcNow;
var item = contentManager.Create<ICommonAspect>("test-item", VersionOptions.Draft, init => { });
Assert.That(item.CreatedUtc, Is.EqualTo(createUtc));
Assert.That(item.PublishedUtc, Is.Null);
_clock.Advance(TimeSpan.FromMinutes(1));
var publishUtc = _clock.UtcNow;
contentManager.Publish(item.ContentItem);
// db records need to be updated before seeking by published flags
_session.Flush();
_clock.Advance(TimeSpan.FromMinutes(1));
var unpublishUtc = _clock.UtcNow;
contentManager.Unpublish(item.ContentItem);
// db records need to be updated before seeking by published flags
_session.Flush();
_session.Clear();
var publishedItem = contentManager.Get<ICommonAspect>(item.ContentItem.Id, VersionOptions.Published);
var latestItem = contentManager.Get<ICommonAspect>(item.ContentItem.Id, VersionOptions.Latest);
var draftItem = contentManager.Get<ICommonAspect>(item.ContentItem.Id, VersionOptions.Draft);
var allVersions = contentManager.GetAllVersions(item.ContentItem.Id);
Assert.That(publishedItem, Is.Null);
Assert.That(latestItem, Is.Not.Null);
Assert.That(draftItem, Is.Not.Null);
Assert.That(allVersions.Count(), Is.EqualTo(1));
Assert.That(publishUtc, Is.Not.EqualTo(unpublishUtc));
Assert.That(latestItem.PublishedUtc, Is.EqualTo(publishUtc));
Assert.That(latestItem.VersionPublishedUtc, Is.EqualTo(publishUtc));
Assert.That(latestItem.ContentItem.VersionRecord.Latest, Is.True);
Assert.That(latestItem.ContentItem.VersionRecord.Published, Is.False);
}
} }
} }

View File

@@ -39,6 +39,10 @@
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\moq\Moq.dll</HintPath> <HintPath>..\..\lib\moq\Moq.dll</HintPath>
</Reference> </Reference>
<Reference Include="NHibernate, Version=2.1.2.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\fluentnhibernate\NHibernate.dll</HintPath>
</Reference>
<Reference Include="NHibernate.ByteCode.Castle, Version=2.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL"> <Reference Include="NHibernate.ByteCode.Castle, Version=2.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\fluentnhibernate\NHibernate.ByteCode.Castle.dll</HintPath> <HintPath>..\..\lib\fluentnhibernate\NHibernate.ByteCode.Castle.dll</HintPath>
@@ -73,6 +77,10 @@
<Project>{6CB3EB30-F725-45C0-9742-42599BA8E8D2}</Project> <Project>{6CB3EB30-F725-45C0-9742-42599BA8E8D2}</Project>
<Name>Orchard.Tests.Packages</Name> <Name>Orchard.Tests.Packages</Name>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\Orchard.Tests\Orchard.Tests.csproj">
<Project>{ABC826D4-2FA1-4F2F-87DE-E6095F653810}</Project>
<Name>Orchard.Tests</Name>
</ProjectReference>
<ProjectReference Include="..\Orchard.Web\Core\Orchard.Core.csproj"> <ProjectReference Include="..\Orchard.Web\Core\Orchard.Core.csproj">
<Project>{9916839C-39FC-4CEB-A5AF-89CA7E87119F}</Project> <Project>{9916839C-39FC-4CEB-A5AF-89CA7E87119F}</Project>
<Name>Orchard.Core</Name> <Name>Orchard.Core</Name>

View File

@@ -125,15 +125,15 @@ namespace Orchard.Tests.ContentManagement {
var model = _manager.Get(modelRecord.Id); var model = _manager.Get(modelRecord.Id);
// create a gamma record //// create a gamma record
var gamma = new GammaRecord { //var gamma = new GammaRecord {
ContentItemRecord = _container.Resolve<IRepository<ContentItemRecord>>().Get(model.Id), // ContentItemRecord = _container.Resolve<IRepository<ContentItemRecord>>().Get(model.Id),
Frap = "foo" // Frap = "foo"
}; //};
_container.Resolve<IRepository<GammaRecord>>().Create(gamma); //_container.Resolve<IRepository<GammaRecord>>().Create(gamma);
_session.Flush(); //_session.Flush();
_session.Clear(); //_session.Clear();
// re-fetch from database // re-fetch from database
model = _manager.Get(modelRecord.Id); model = _manager.Get(modelRecord.Id);

View File

@@ -14,7 +14,7 @@ namespace Orchard.Tests.ContentManagement.Handlers {
var part = new TestModelPart(); var part = new TestModelPart();
contentItem.Weld(part); contentItem.Weld(part);
((IContentHandler)modelDriver).Creating(new CreateContentContext { ContentItem = contentItem }); ((IContentHandler)modelDriver).Creating(new CreateContentContext(contentItem));
Assert.That(part.CreatingCalled, Is.True); Assert.That(part.CreatingCalled, Is.True);
} }

View File

@@ -10,24 +10,9 @@ namespace Orchard.Core.Common.Models {
private readonly LazyField<IUser> _owner = new LazyField<IUser>(); private readonly LazyField<IUser> _owner = new LazyField<IUser>();
private readonly LazyField<IContent> _container = new LazyField<IContent>(); private readonly LazyField<IContent> _container = new LazyField<IContent>();
public LazyField<IUser> OwnerField { public LazyField<IUser> OwnerField { get { return _owner; } }
get { return _owner; }
}
public LazyField<IContent> ContainerField {
get { return _container; }
}
public LazyField<IContent> ContainerField { get { return _container; } }
DateTime? ICommonAspect.CreatedUtc {
get { return Record.CreatedUtc;}
set { Record.CreatedUtc = value;}
}
DateTime? ICommonAspect.ModifiedUtc {
get { return Record.ModifiedUtc;}
set { Record.ModifiedUtc = value;}
}
public IUser Owner { public IUser Owner {
get { return _owner.Value; } get { return _owner.Value; }
@@ -38,5 +23,60 @@ namespace Orchard.Core.Common.Models {
get { return _container.Value; } get { return _container.Value; }
set { _container.Value = value; } set { _container.Value = value; }
} }
public DateTime? CreatedUtc {
get { return Record.CreatedUtc; }
set { Record.CreatedUtc = value; }
}
public DateTime? PublishedUtc {
get { return Record.PublishedUtc; }
set { Record.PublishedUtc = value; }
}
public DateTime? ModifiedUtc {
get { return Record.ModifiedUtc; }
set { Record.ModifiedUtc = value; }
}
CommonVersionRecord VersionRecord {
get {
var versionPart = this.As<ContentPart<CommonVersionRecord>>();
return versionPart == null ? null : versionPart.Record;
}
}
public DateTime? VersionCreatedUtc {
get {
return VersionRecord == null ? CreatedUtc : VersionRecord.CreatedUtc;
}
set {
if (VersionRecord != null) {
VersionRecord.CreatedUtc = value;
}
}
}
public DateTime? VersionPublishedUtc {
get {
return VersionRecord == null ? PublishedUtc : VersionRecord.PublishedUtc;
}
set {
if (VersionRecord != null) {
VersionRecord.PublishedUtc = value;
}
}
}
public DateTime? VersionModifiedUtc {
get {
return VersionRecord == null ? ModifiedUtc : VersionRecord.ModifiedUtc;
}
set {
if (VersionRecord != null) {
VersionRecord.ModifiedUtc = value;
}
}
}
} }
} }

View File

@@ -1,17 +1,17 @@
using System; using JetBrains.Annotations;
using Orchard.Core.Common.Models; using Orchard.Core.Common.Models;
using Orchard.Core.Common.Records; using Orchard.Core.Common.Records;
using Orchard.Core.Common.ViewModels; using Orchard.Core.Common.ViewModels;
using Orchard.Data; using Orchard.Data;
using Orchard.Localization; using Orchard.Localization;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.ContentManagement.Aspects;
using Orchard.ContentManagement.Handlers; using Orchard.ContentManagement.Handlers;
using Orchard.ContentManagement.ViewModels; using Orchard.ContentManagement.ViewModels;
using Orchard.Security; using Orchard.Security;
using Orchard.Services; using Orchard.Services;
namespace Orchard.Core.Common.Providers { namespace Orchard.Core.Common.Providers {
[UsedImplicitly]
public class CommonAspectHandler : ContentHandler { public class CommonAspectHandler : ContentHandler {
private readonly IClock _clock; private readonly IClock _clock;
private readonly IAuthenticationService _authenticationService; private readonly IAuthenticationService _authenticationService;
@@ -20,7 +20,8 @@ namespace Orchard.Core.Common.Providers {
private readonly IContentManager _contentManager; private readonly IContentManager _contentManager;
public CommonAspectHandler( public CommonAspectHandler(
IRepository<CommonRecord> repository, IRepository<CommonRecord> commonRepository,
IRepository<CommonVersionRecord> commonVersionRepository,
IClock clock, IClock clock,
IAuthenticationService authenticationService, IAuthenticationService authenticationService,
IAuthorizationService authorizationService, IAuthorizationService authorizationService,
@@ -34,10 +35,16 @@ namespace Orchard.Core.Common.Providers {
_contentManager = contentManager; _contentManager = contentManager;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
Filters.Add(StorageFilter.For(repository)); Filters.Add(StorageFilter.For(commonRepository));
Filters.Add(StorageFilter.For(commonVersionRepository));
OnActivated<CommonAspect>(PropertySetHandlers); OnActivated<CommonAspect>(PropertySetHandlers);
OnActivated<CommonAspect>(DefaultTimestampsAndOwner); OnActivated<CommonAspect>(AssignCreatingOwner);
OnActivated <ContentPart<CommonRecord>>(AssignCreatingDates);
OnActivated<ContentPart<CommonVersionRecord>>(AssignCreatingDates);
OnVersioned<ContentPart<CommonVersionRecord>>(AssignVersioningDates);
OnPublishing<ContentPart<CommonRecord>>(AssignPublishingDates);
OnPublishing<ContentPart<CommonVersionRecord>>(AssignPublishingDates);
OnLoaded<CommonAspect>(LazyLoadHandlers); OnLoaded<CommonAspect>(LazyLoadHandlers);
//OnGetDisplayViewModel<CommonAspect>(); //OnGetDisplayViewModel<CommonAspect>();
@@ -47,21 +54,53 @@ namespace Orchard.Core.Common.Providers {
public Localizer T { get; set; } public Localizer T { get; set; }
void DefaultTimestampsAndOwner(ActivatedContentContext context, CommonAspect instance) {
// assign default create/modified dates
if (instance.Record.CreatedUtc == null) {
instance.Record.CreatedUtc = _clock.UtcNow;
}
if (instance.Record.ModifiedUtc == null) {
instance.Record.ModifiedUtc = _clock.UtcNow;
}
void AssignCreatingOwner(ActivatedContentContext context, CommonAspect part) {
// and use the current user as Owner // and use the current user as Owner
if (instance.Record.OwnerId == 0) { if (part.Record.OwnerId == 0) {
((ICommonAspect)instance).Owner = _authenticationService.GetAuthenticatedUser(); part.Owner = _authenticationService.GetAuthenticatedUser();
} }
} }
void AssignCreatingDates(ActivatedContentContext context, ContentPart<CommonRecord> part) {
// assign default create/modified dates
part.Record.CreatedUtc = _clock.UtcNow;
part.Record.ModifiedUtc = _clock.UtcNow;
}
void AssignCreatingDates(ActivatedContentContext context, ContentPart<CommonVersionRecord> part) {
// assign default create/modified dates
part.Record.CreatedUtc = _clock.UtcNow;
part.Record.ModifiedUtc = _clock.UtcNow;
}
void AssignVersioningDates(VersionContentContext context, ContentPart<CommonVersionRecord> existing, ContentPart<CommonVersionRecord> building) {
// assign create/modified dates for the new version
building.Record.CreatedUtc = _clock.UtcNow;
building.Record.ModifiedUtc = _clock.UtcNow;
// publish date should be null until publish method called
building.Record.PublishedUtc = null;
}
void AssignPublishingDates(PublishContentContext context, ContentPart<CommonRecord> part) {
// don't assign dates when unpublishing
if (context.PublishingItemVersionRecord == null)
return;
// assign version-agnostic publish date
part.Record.PublishedUtc = _clock.UtcNow;
}
void AssignPublishingDates(PublishContentContext context, ContentPart<CommonVersionRecord> part) {
// don't assign dates when unpublishing
if (context.PublishingItemVersionRecord == null)
return;
// assign version-specific publish date
part.Record.PublishedUtc = _clock.UtcNow;
}
void LazyLoadHandlers(LoadContentContext context, CommonAspect aspect) { void LazyLoadHandlers(LoadContentContext context, CommonAspect aspect) {
// add handlers that will load content for id's just-in-time // add handlers that will load content for id's just-in-time
aspect.OwnerField.Loader(() => _contentManager.Get<IUser>(aspect.Record.OwnerId)); aspect.OwnerField.Loader(() => _contentManager.Get<IUser>(aspect.Record.OwnerId));
@@ -109,7 +148,8 @@ namespace Orchard.Core.Common.Providers {
private void UpdateEditor(UpdateEditorModelContext context, CommonAspect instance) { private void UpdateEditor(UpdateEditorModelContext context, CommonAspect instance) {
// this event is hooked so the modified timestamp is changed when an edit-post occurs. // this event is hooked so the modified timestamp is changed when an edit-post occurs.
// kind of a loose rule of thumb. may not be sufficient // kind of a loose rule of thumb. may not be sufficient
instance.Record.ModifiedUtc = _clock.UtcNow; instance.ModifiedUtc = _clock.UtcNow;
instance.VersionModifiedUtc = _clock.UtcNow;
var currentUser = _authenticationService.GetAuthenticatedUser(); var currentUser = _authenticationService.GetAuthenticatedUser();
if (!_authorizationService.CheckAccess(currentUser, Permissions.ChangeOwner)) { if (!_authorizationService.CheckAccess(currentUser, Permissions.ChangeOwner)) {

View File

@@ -6,6 +6,7 @@ namespace Orchard.Core.Common.Records {
public virtual int OwnerId { get; set; } public virtual int OwnerId { get; set; }
public virtual ContentItemRecord Container { get; set; } public virtual ContentItemRecord Container { get; set; }
public virtual DateTime? CreatedUtc { get; set; } public virtual DateTime? CreatedUtc { get; set; }
public virtual DateTime? PublishedUtc { get; set; }
public virtual DateTime? ModifiedUtc { get; set; } public virtual DateTime? ModifiedUtc { get; set; }
} }
} }

View File

@@ -0,0 +1,10 @@
using System;
using Orchard.ContentManagement.Records;
namespace Orchard.Core.Common.Records {
public class CommonVersionRecord : ContentPartVersionRecord {
public virtual DateTime? CreatedUtc { get; set; }
public virtual DateTime? PublishedUtc { get; set; }
public virtual DateTime? ModifiedUtc { get; set; }
}
}

View File

@@ -63,6 +63,7 @@
<ItemGroup> <ItemGroup>
<Compile Include="Common\Controllers\BodyDriver.cs" /> <Compile Include="Common\Controllers\BodyDriver.cs" />
<Compile Include="Common\Permissions.cs" /> <Compile Include="Common\Permissions.cs" />
<Compile Include="Common\Records\CommonVersionRecord.cs" />
<Compile Include="Common\Utilities\LazyField.cs" /> <Compile Include="Common\Utilities\LazyField.cs" />
<Compile Include="Common\Providers\CommonAspectHandler.cs" /> <Compile Include="Common\Providers\CommonAspectHandler.cs" />
<Compile Include="Common\Models\CommonAspect.cs" /> <Compile Include="Common\Models\CommonAspect.cs" />

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Web.Mvc; using System.Web.Mvc;
using Orchard.ContentManagement.Aspects;
using Orchard.Core.Common.Models; using Orchard.Core.Common.Models;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.Security; using Orchard.Security;
@@ -23,13 +24,13 @@ namespace Orchard.Blogs.Models {
} }
public Blog Blog { public Blog Blog {
get { return this.As<CommonAspect>().Container.As<Blog>(); } get { return this.As<ICommonAspect>().Container.As<Blog>(); }
set { this.As<CommonAspect>().Container = value; } set { this.As<ICommonAspect>().Container = value; }
} }
public IUser Creator { public IUser Creator {
get { return this.As<CommonAspect>().Owner; } get { return this.As<ICommonAspect>().Owner; }
set { this.As<CommonAspect>().Owner = value; } set { this.As<ICommonAspect>().Owner = value; }
} }
public DateTime? Published public DateTime? Published

View File

@@ -38,11 +38,11 @@
valueItem = (value as IContent).ContentItem; valueItem = (value as IContent).ContentItem;
} }
if (valueItem != null) { if (valueItem != null) {
%><%=Html.ActionLink(T("{0} #{1} v{2}", valueItem.ContentType, valueItem.Id).ToString(), "details", new { valueItem.Id }, new { })%><% %><%=Html.ActionLink(T("{0} #{1} v{2}", valueItem.ContentType, valueItem.Id, valueItem.Version).ToString(), "details", new { valueItem.Id }, new { })%><%
} }
%> %>
<ul style="margin-left: 20px"> <ul style="margin-left: 20px">
<%if (value == null || prop.PropertyType.IsPrimitive || prop.PropertyType == typeof(string)) { } <%if (value == null || prop.PropertyType.IsPrimitive || prop.PropertyType == typeof(string) || prop.PropertyType == typeof(DateTime?)) { }
else if (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType)) { else if (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType)) {
foreach (var item in value as IEnumerable) { foreach (var item in value as IEnumerable) {
%> %>

View File

@@ -133,8 +133,10 @@ namespace Orchard.Pages.Controllers {
Page page = _pageService.Create(publishNow); Page page = _pageService.Create(publishNow);
model.Page = Services.ContentManager.UpdateEditorModel(page, this); model.Page = Services.ContentManager.UpdateEditorModel(page, this);
if (!ModelState.IsValid) if (!ModelState.IsValid) {
Services.TransactionManager.Cancel();
return View(model); return View(model);
}
var session = _sessionLocator.For(typeof(Page)); var session = _sessionLocator.For(typeof(Page));
session.Flush(); session.Flush();
@@ -146,7 +148,7 @@ namespace Orchard.Pages.Controllers {
if (!Services.Authorizer.Authorize(Permissions.ModifyPages, T("Couldn't edit page"))) if (!Services.Authorizer.Authorize(Permissions.ModifyPages, T("Couldn't edit page")))
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
Page page = _pageService.GetPageOrDraft(pageSlug); Page page = _pageService.GetLatest(pageSlug);
if (page == null) if (page == null)
return new NotFoundResult(); return new NotFoundResult();

View File

@@ -1,4 +1,6 @@
using JetBrains.Annotations; using JetBrains.Annotations;
using Orchard.ContentManagement;
using Orchard.Core.Common.Records;
using Orchard.Pages.Controllers; using Orchard.Pages.Controllers;
using Orchard.Core.Common.Models; using Orchard.Core.Common.Models;
using Orchard.Data; using Orchard.Data;
@@ -10,6 +12,7 @@ namespace Orchard.Pages.Models {
public PageHandler(IRepository<PageRecord> repository) { public PageHandler(IRepository<PageRecord> repository) {
Filters.Add(new ActivatingFilter<Page>(PageDriver.ContentType.Name)); Filters.Add(new ActivatingFilter<Page>(PageDriver.ContentType.Name));
Filters.Add(new ActivatingFilter<CommonAspect>(PageDriver.ContentType.Name)); Filters.Add(new ActivatingFilter<CommonAspect>(PageDriver.ContentType.Name));
Filters.Add(new ActivatingFilter<ContentPart<CommonVersionRecord>>(PageDriver.ContentType.Name));
Filters.Add(new ActivatingFilter<RoutableAspect>(PageDriver.ContentType.Name)); Filters.Add(new ActivatingFilter<RoutableAspect>(PageDriver.ContentType.Name));
Filters.Add(new ActivatingFilter<BodyAspect>(PageDriver.ContentType.Name)); Filters.Add(new ActivatingFilter<BodyAspect>(PageDriver.ContentType.Name));
Filters.Add(new StorageFilter<PageRecord>(repository)); Filters.Add(new StorageFilter<PageRecord>(repository));

View File

@@ -7,6 +7,7 @@ namespace Orchard.Pages.Services {
IEnumerable<Page> Get(PageStatus status); IEnumerable<Page> Get(PageStatus status);
Page Get(string slug); Page Get(string slug);
Page GetPageOrDraft(string slug); Page GetPageOrDraft(string slug);
Page GetLatest(string slug);
Page GetLatest(int id); Page GetLatest(int id);
Page New(); Page New();
Page Create(bool publishNow); Page Create(bool publishNow);

View File

@@ -47,10 +47,14 @@ namespace Orchard.Pages.Services {
return _contentManager.Get<Page>(id, VersionOptions.Latest); return _contentManager.Get<Page>(id, VersionOptions.Latest);
} }
public Page GetPageOrDraft(string slug) { public Page GetLatest(string slug) {
Page page = _contentManager.Query<Page, PageRecord>(VersionOptions.Latest) return _contentManager.Query<Page, PageRecord>(VersionOptions.Latest)
.Join<RoutableRecord>().Where(rr => rr.Slug == slug) .Join<RoutableRecord>().Where(rr => rr.Slug == slug)
.List().FirstOrDefault(); .Slice(0, 1).FirstOrDefault();
}
public Page GetPageOrDraft(string slug) {
Page page = GetLatest(slug);
return _contentManager.GetDraftRequired<Page>(page.Id); return _contentManager.GetDraftRequired<Page>(page.Id);
} }

View File

@@ -6,9 +6,15 @@ using Orchard.Security;
namespace Orchard.ContentManagement.Aspects { namespace Orchard.ContentManagement.Aspects {
public interface ICommonAspect : IContent { public interface ICommonAspect : IContent {
DateTime? CreatedUtc { get; set; }
DateTime? ModifiedUtc { get; set; }
IUser Owner { get; set; } IUser Owner { get; set; }
IContent Container { get; set; } IContent Container { get; set; }
DateTime? CreatedUtc { get; set; }
DateTime? PublishedUtc { get; set; }
DateTime? ModifiedUtc { get; set; }
DateTime? VersionCreatedUtc { get; set; }
DateTime? VersionPublishedUtc { get; set; }
DateTime? VersionModifiedUtc { get; set; }
} }
} }

View File

@@ -123,13 +123,7 @@ namespace Orchard.ContentManagement {
contentItem.VersionRecord = versionRecord; contentItem.VersionRecord = versionRecord;
// create a context with a new instance to load // create a context with a new instance to load
var context = new LoadContentContext { var context = new LoadContentContext(contentItem);
Id = contentItem.Id,
ContentType = contentItem.ContentType,
ContentItem = contentItem,
ContentItemRecord = contentItem.Record,
ContentItemVersionRecord = contentItem.VersionRecord,
};
// invoke handlers to acquire state, or at least establish lazy loading callbacks // invoke handlers to acquire state, or at least establish lazy loading callbacks
foreach (var handler in Handlers) { foreach (var handler in Handlers) {
@@ -158,14 +152,57 @@ namespace Orchard.ContentManagement {
if (contentItem.VersionRecord.Published) { if (contentItem.VersionRecord.Published) {
return; return;
} }
// create a context for the item and it's previous published record
var previous = contentItem.Record.Versions.SingleOrDefault(x => x.Published); var previous = contentItem.Record.Versions.SingleOrDefault(x => x.Published);
var context = new PublishContentContext(contentItem, previous);
// invoke handlers to acquire state, or at least establish lazy loading callbacks
foreach (var handler in Handlers) {
handler.Publishing(context);
}
if (previous != null) { if (previous != null) {
previous.Published = false; previous.Published = false;
//_contentItemVersionRepository.Update(previous);
} }
contentItem.VersionRecord.Published = true; contentItem.VersionRecord.Published = true;
//_contentItemVersionRepository.Update(contentItem.VersionRecord);
//TODO: fire content handler events foreach (var handler in Handlers) {
handler.Published(context);
}
}
public virtual void Unpublish(ContentItem contentItem) {
ContentItem publishedItem;
if (contentItem.VersionRecord.Published) {
// the version passed in is the published one
publishedItem = contentItem;
}
else {
// try to locate the published version of this item
publishedItem = Get(contentItem.Id, VersionOptions.Published);
}
if (publishedItem == null) {
// no published version exists. no work to perform.
return;
}
// create a context for the item. the publishing version is null in this case
// and the previous version is the one active prior to unpublishing. handlers
// should take this null check into account
var context = new PublishContentContext(contentItem, publishedItem.VersionRecord) {
PublishingItemVersionRecord = null
};
foreach (var handler in Handlers) {
handler.Publishing(context);
}
publishedItem.VersionRecord.Published = false;
foreach (var handler in Handlers) {
handler.Published(context);
}
} }
public virtual void Remove(ContentItem contentItem) { public virtual void Remove(ContentItem contentItem) {
@@ -260,13 +297,7 @@ namespace Orchard.ContentManagement {
// build a context with the initialized instance to create // build a context with the initialized instance to create
var context = new CreateContentContext { var context = new CreateContentContext(contentItem);
Id = contentItem.Id,
ContentType = contentItem.ContentType,
ContentItemRecord = contentItem.Record,
ContentItemVersionRecord = contentItem.VersionRecord,
ContentItem = contentItem
};
// invoke handlers to add information to persistent stores // invoke handlers to add information to persistent stores

View File

@@ -22,23 +22,16 @@ namespace Orchard.ContentManagement.Drivers {
} }
void IContentHandler.Activating(ActivatingContentContext context) { } void IContentHandler.Activating(ActivatingContentContext context) { }
void IContentHandler.Activated(ActivatedContentContext context) { } void IContentHandler.Activated(ActivatedContentContext context) { }
void IContentHandler.Creating(CreateContentContext context) { } void IContentHandler.Creating(CreateContentContext context) { }
void IContentHandler.Created(CreateContentContext context) { } void IContentHandler.Created(CreateContentContext context) { }
void IContentHandler.Loading(LoadContentContext context) { } void IContentHandler.Loading(LoadContentContext context) { }
void IContentHandler.Loaded(LoadContentContext context) { } void IContentHandler.Loaded(LoadContentContext context) { }
void IContentHandler.Versioning(VersionContentContext context) { } void IContentHandler.Versioning(VersionContentContext context) { }
void IContentHandler.Versioned(VersionContentContext context) { } void IContentHandler.Versioned(VersionContentContext context) { }
void IContentHandler.Publishing(PublishContentContext context) { }
void IContentHandler.Published(PublishContentContext context) { }
void IContentHandler.Removing(RemoveContentContext context) { } void IContentHandler.Removing(RemoveContentContext context) { }
void IContentHandler.Removed(RemoveContentContext context) { } void IContentHandler.Removed(RemoveContentContext context) { }

View File

@@ -21,23 +21,16 @@ namespace Orchard.ContentManagement.Drivers {
} }
void IContentHandler.Activating(ActivatingContentContext context) { } void IContentHandler.Activating(ActivatingContentContext context) { }
void IContentHandler.Activated(ActivatedContentContext context) { } void IContentHandler.Activated(ActivatedContentContext context) { }
void IContentHandler.Creating(CreateContentContext context) { } void IContentHandler.Creating(CreateContentContext context) { }
void IContentHandler.Created(CreateContentContext context) { } void IContentHandler.Created(CreateContentContext context) { }
void IContentHandler.Loading(LoadContentContext context) { } void IContentHandler.Loading(LoadContentContext context) { }
void IContentHandler.Loaded(LoadContentContext context) { } void IContentHandler.Loaded(LoadContentContext context) { }
void IContentHandler.Versioning(VersionContentContext context) { } void IContentHandler.Versioning(VersionContentContext context) { }
void IContentHandler.Versioned(VersionContentContext context) { } void IContentHandler.Versioned(VersionContentContext context) { }
void IContentHandler.Publishing(PublishContentContext context) { }
void IContentHandler.Published(PublishContentContext context) { }
void IContentHandler.Removing(RemoveContentContext context) { } void IContentHandler.Removing(RemoveContentContext context) { }
void IContentHandler.Removed(RemoveContentContext context) { } void IContentHandler.Removed(RemoveContentContext context) { }
void IContentHandler.GetContentItemMetadata(GetContentItemMetadataContext context) { } void IContentHandler.GetContentItemMetadata(GetContentItemMetadataContext context) { }

View File

@@ -41,6 +41,14 @@ namespace Orchard.ContentManagement.Handlers {
Filters.Add(new InlineStorageFilter<TPart> { OnVersioned = handler }); Filters.Add(new InlineStorageFilter<TPart> { OnVersioned = handler });
} }
protected void OnPublishing<TPart>(Action<PublishContentContext, TPart> handler) where TPart : class, IContent {
Filters.Add(new InlineStorageFilter<TPart> { OnPublishing = handler });
}
protected void OnPublished<TPart>(Action<PublishContentContext, TPart> handler) where TPart : class, IContent {
Filters.Add(new InlineStorageFilter<TPart> { OnPublished = handler });
}
protected void OnRemoving<TPart>(Action<RemoveContentContext, TPart> handler) where TPart : class, IContent { protected void OnRemoving<TPart>(Action<RemoveContentContext, TPart> handler) where TPart : class, IContent {
Filters.Add(new InlineStorageFilter<TPart> { OnRemoving = handler }); Filters.Add(new InlineStorageFilter<TPart> { OnRemoving = handler });
} }
@@ -72,6 +80,8 @@ namespace Orchard.ContentManagement.Handlers {
public Action<LoadContentContext, TPart> OnLoaded { get; set; } public Action<LoadContentContext, TPart> OnLoaded { get; set; }
public Action<VersionContentContext, TPart, TPart> OnVersioning { get; set; } public Action<VersionContentContext, TPart, TPart> OnVersioning { get; set; }
public Action<VersionContentContext, TPart, TPart> OnVersioned { get; set; } public Action<VersionContentContext, TPart, TPart> OnVersioned { get; set; }
public Action<PublishContentContext, TPart> OnPublishing { get; set; }
public Action<PublishContentContext, TPart> OnPublished { get; set; }
public Action<RemoveContentContext, TPart> OnRemoving { get; set; } public Action<RemoveContentContext, TPart> OnRemoving { get; set; }
public Action<RemoveContentContext, TPart> OnRemoved { get; set; } public Action<RemoveContentContext, TPart> OnRemoved { get; set; }
protected override void Activated(ActivatedContentContext context, TPart instance) { protected override void Activated(ActivatedContentContext context, TPart instance) {
@@ -95,6 +105,12 @@ namespace Orchard.ContentManagement.Handlers {
protected override void Versioned(VersionContentContext context, TPart existing, TPart building) { protected override void Versioned(VersionContentContext context, TPart existing, TPart building) {
if (OnVersioned != null) OnVersioned(context, existing, building); if (OnVersioned != null) OnVersioned(context, existing, building);
} }
protected override void Publishing(PublishContentContext context, TPart instance) {
if (OnPublishing != null) OnPublishing(context, instance);
}
protected override void Published(PublishContentContext context, TPart instance) {
if (OnPublished != null) OnPublished(context, instance);
}
protected override void Removing(RemoveContentContext context, TPart instance) { protected override void Removing(RemoveContentContext context, TPart instance) {
if (OnRemoving != null) OnRemoving(context, instance); if (OnRemoving != null) OnRemoving(context, instance);
} }
@@ -161,6 +177,7 @@ namespace Orchard.ContentManagement.Handlers {
filter.Loaded(context); filter.Loaded(context);
Loaded(context); Loaded(context);
} }
void IContentHandler.Versioning(VersionContentContext context) { void IContentHandler.Versioning(VersionContentContext context) {
foreach (var filter in Filters.OfType<IContentStorageFilter>()) foreach (var filter in Filters.OfType<IContentStorageFilter>())
filter.Versioning(context); filter.Versioning(context);
@@ -172,6 +189,19 @@ namespace Orchard.ContentManagement.Handlers {
filter.Versioned(context); filter.Versioned(context);
Versioned(context); Versioned(context);
} }
void IContentHandler.Publishing(PublishContentContext context) {
foreach (var filter in Filters.OfType<IContentStorageFilter>())
filter.Publishing(context);
Publishing(context);
}
void IContentHandler.Published(PublishContentContext context) {
foreach (var filter in Filters.OfType<IContentStorageFilter>())
filter.Published(context);
Published(context);
}
void IContentHandler.Removing(RemoveContentContext context) { void IContentHandler.Removing(RemoveContentContext context) {
foreach (var filter in Filters.OfType<IContentStorageFilter>()) foreach (var filter in Filters.OfType<IContentStorageFilter>())
filter.Removing(context); filter.Removing(context);
@@ -218,6 +248,9 @@ namespace Orchard.ContentManagement.Handlers {
protected virtual void Versioning(VersionContentContext context) { } protected virtual void Versioning(VersionContentContext context) { }
protected virtual void Versioned(VersionContentContext context) { } protected virtual void Versioned(VersionContentContext context) { }
protected virtual void Publishing(PublishContentContext context) { }
protected virtual void Published(PublishContentContext context) { }
protected virtual void Removing(RemoveContentContext context) { } protected virtual void Removing(RemoveContentContext context) { }
protected virtual void Removed(RemoveContentContext context) { } protected virtual void Removed(RemoveContentContext context) { }

View File

@@ -1,12 +1,11 @@
using Orchard.ContentManagement.Records; using Orchard.ContentManagement.Records;
namespace Orchard.ContentManagement.Handlers { namespace Orchard.ContentManagement.Handlers {
public class CreateContentContext { public class CreateContentContext : ContentContextBase {
public int Id { get; set; } public CreateContentContext(ContentItem contentItem) : base(contentItem) {
public string ContentType { get; set; } ContentItemVersionRecord = contentItem.VersionRecord;
}
public ContentItem ContentItem { get; set; }
public ContentItemRecord ContentItemRecord { get; set; }
public ContentItemVersionRecord ContentItemVersionRecord { get; set; } public ContentItemVersionRecord ContentItemVersionRecord { get; set; }
} }
} }

View File

@@ -12,6 +12,8 @@ namespace Orchard.ContentManagement.Handlers {
void Loaded(LoadContentContext context); void Loaded(LoadContentContext context);
void Versioning(VersionContentContext context); void Versioning(VersionContentContext context);
void Versioned(VersionContentContext context); void Versioned(VersionContentContext context);
void Publishing(PublishContentContext context);
void Published(PublishContentContext context);
void Removing(RemoveContentContext context); void Removing(RemoveContentContext context);
void Removed(RemoveContentContext context); void Removed(RemoveContentContext context);

View File

@@ -7,6 +7,8 @@ namespace Orchard.ContentManagement.Handlers {
void Loaded(LoadContentContext context); void Loaded(LoadContentContext context);
void Versioning(VersionContentContext context); void Versioning(VersionContentContext context);
void Versioned(VersionContentContext context); void Versioned(VersionContentContext context);
void Publishing(PublishContentContext context);
void Published(PublishContentContext context);
void Removing(RemoveContentContext context); void Removing(RemoveContentContext context);
void Removed(RemoveContentContext context); void Removed(RemoveContentContext context);
} }

View File

@@ -2,19 +2,42 @@ using System;
using Orchard.ContentManagement.Records; using Orchard.ContentManagement.Records;
namespace Orchard.ContentManagement.Handlers { namespace Orchard.ContentManagement.Handlers {
public class LoadContentContext {
public class ContentContextBase {
protected ContentContextBase (ContentItem contentItem) {
ContentItem = contentItem;
Id = contentItem.Id;
ContentType = contentItem.ContentType;
ContentItemRecord = contentItem.Record;
}
public int Id { get; set; } public int Id { get; set; }
public string ContentType { get; set; } public string ContentType { get; set; }
public ContentItem ContentItem { get; set; } public ContentItem ContentItem { get; set; }
public ContentItemRecord ContentItemRecord { get; set; } public ContentItemRecord ContentItemRecord { get; set; }
}
public class LoadContentContext : ContentContextBase {
public LoadContentContext(ContentItem contentItem) : base(contentItem) {
ContentItemVersionRecord = contentItem.VersionRecord;
}
public ContentItemVersionRecord ContentItemVersionRecord { get; set; } public ContentItemVersionRecord ContentItemVersionRecord { get; set; }
} }
public class RemoveContentContext { public class PublishContentContext : ContentContextBase {
public int Id { get; set; } public PublishContentContext(ContentItem contentItem, ContentItemVersionRecord previousItemVersionRecord) : base(contentItem) {
public string ContentType { get; set; } PublishingItemVersionRecord = contentItem.VersionRecord;
public ContentItem ContentItem { get; set; } PreviousItemVersionRecord = previousItemVersionRecord;
public ContentItemRecord ContentItemRecord { get; set; } }
public ContentItemVersionRecord PublishingItemVersionRecord { get; set; }
public ContentItemVersionRecord PreviousItemVersionRecord { get; set; }
}
public class RemoveContentContext : ContentContextBase {
public RemoveContentContext(ContentItem contentItem) : base(contentItem) {
}
} }
public class VersionContentContext { public class VersionContentContext {

View File

@@ -40,13 +40,7 @@ namespace Orchard.ContentManagement.Handlers {
instance.Record = record; instance.Record = record;
} }
else { else {
var createContext = new CreateContentContext { var createContext = new CreateContentContext(context.ContentItem);
ContentItem = context.ContentItem,
ContentItemRecord = context.ContentItemRecord,
ContentItemVersionRecord = context.ContentItemVersionRecord,
ContentType = context.ContentType,
Id = context.Id
};
Creating(createContext, instance); Creating(createContext, instance);
} }
} }
@@ -55,31 +49,4 @@ namespace Orchard.ContentManagement.Handlers {
building.Record = existing.Record; building.Record = existing.Record;
} }
} }
public class StorageVersionFilter<TRecord> : StorageFilter<TRecord> where TRecord : ContentPartVersionRecord, new() {
public StorageVersionFilter(IRepository<TRecord> repository)
: base(repository) {
}
protected override TRecord GetRecord(LoadContentContext context) {
return _repository.Get(context.ContentItemVersionRecord.Id);
}
protected override void Creating(CreateContentContext context, ContentPart<TRecord> instance) {
instance.Record.ContentItemRecord = context.ContentItemRecord;
instance.Record.ContentItemVersionRecord = context.ContentItemVersionRecord;
_repository.Create(instance.Record);
}
protected override void Versioning(VersionContentContext context, ContentPart<TRecord> existing, ContentPart<TRecord> building) {
// move known ORM values over
_repository.Copy(existing.Record, building.Record);
// only the up-reference to the particular version differs at this point
building.Record.ContentItemVersionRecord = context.BuildingItemVersionRecord;
// push the new instance into the transaction and session
_repository.Create(building.Record);
}
}
} }

View File

@@ -8,6 +8,8 @@ namespace Orchard.ContentManagement.Handlers {
protected virtual void Loaded(LoadContentContext context, TPart instance) { } protected virtual void Loaded(LoadContentContext context, TPart instance) { }
protected virtual void Versioning(VersionContentContext context, TPart existing, TPart building) { } protected virtual void Versioning(VersionContentContext context, TPart existing, TPart building) { }
protected virtual void Versioned(VersionContentContext context, TPart existing, TPart building) { } protected virtual void Versioned(VersionContentContext context, TPart existing, TPart building) { }
protected virtual void Publishing(PublishContentContext context, TPart instance) { }
protected virtual void Published(PublishContentContext context, TPart instance) { }
protected virtual void Removing(RemoveContentContext context, TPart instance) { } protected virtual void Removing(RemoveContentContext context, TPart instance) { }
protected virtual void Removed(RemoveContentContext context, TPart instance) { } protected virtual void Removed(RemoveContentContext context, TPart instance) { }
@@ -47,6 +49,16 @@ namespace Orchard.ContentManagement.Handlers {
Versioned(context, context.ExistingContentItem.As<TPart>(), context.BuildingContentItem.As<TPart>()); Versioned(context, context.ExistingContentItem.As<TPart>(), context.BuildingContentItem.As<TPart>());
} }
void IContentStorageFilter.Publishing(PublishContentContext context) {
if (context.ContentItem.Is<TPart>())
Publishing(context, context.ContentItem.As<TPart>());
}
void IContentStorageFilter.Published(PublishContentContext context) {
if (context.ContentItem.Is<TPart>())
Published(context, context.ContentItem.As<TPart>());
}
void IContentStorageFilter.Removing(RemoveContentContext context) { void IContentStorageFilter.Removing(RemoveContentContext context) {
if (context.ContentItem.Is<TPart>()) if (context.ContentItem.Is<TPart>())
Removing(context, context.ContentItem.As<TPart>()); Removing(context, context.ContentItem.As<TPart>());

View File

@@ -0,0 +1,32 @@
using Orchard.ContentManagement.Records;
using Orchard.Data;
namespace Orchard.ContentManagement.Handlers {
public class StorageVersionFilter<TRecord> : StorageFilter<TRecord> where TRecord : ContentPartVersionRecord, new() {
public StorageVersionFilter(IRepository<TRecord> repository)
: base(repository) {
}
protected override TRecord GetRecord(LoadContentContext context) {
return _repository.Get(context.ContentItemVersionRecord.Id);
}
protected override void Creating(CreateContentContext context, ContentPart<TRecord> instance) {
instance.Record.ContentItemRecord = context.ContentItemRecord;
instance.Record.ContentItemVersionRecord = context.ContentItemVersionRecord;
_repository.Create(instance.Record);
}
protected override void Versioning(VersionContentContext context, ContentPart<TRecord> existing, ContentPart<TRecord> building) {
// move known ORM values over
_repository.Copy(existing.Record, building.Record);
// only the up-reference to the particular version differs at this point
building.Record.ContentItemVersionRecord = context.BuildingItemVersionRecord;
// push the new instance into the transaction and session
_repository.Create(building.Record);
}
}
}

View File

@@ -15,6 +15,7 @@ namespace Orchard.ContentManagement {
IEnumerable<ContentItem> GetAllVersions(int id); IEnumerable<ContentItem> GetAllVersions(int id);
void Publish(ContentItem contentItem); void Publish(ContentItem contentItem);
void Unpublish(ContentItem contentItem);
void Remove(ContentItem contentItem); void Remove(ContentItem contentItem);
IContentQuery<ContentItem> Query(); IContentQuery<ContentItem> Query();

View File

@@ -13,5 +13,6 @@ namespace Orchard.ContentManagement.Records {
public virtual int Id { get; set; } public virtual int Id { get; set; }
public virtual ContentTypeRecord ContentType { get; set; } public virtual ContentTypeRecord ContentType { get; set; }
public virtual IList<ContentItemVersionRecord> Versions { get; set; } public virtual IList<ContentItemVersionRecord> Versions { get; set; }
} }
} }

View File

@@ -161,6 +161,7 @@
<Compile Include="ContentManagement\Handlers\LoadContentContext.cs" /> <Compile Include="ContentManagement\Handlers\LoadContentContext.cs" />
<Compile Include="ContentManagement\Handlers\StorageFilter.cs" /> <Compile Include="ContentManagement\Handlers\StorageFilter.cs" />
<Compile Include="ContentManagement\Handlers\StorageFilterBase.cs" /> <Compile Include="ContentManagement\Handlers\StorageFilterBase.cs" />
<Compile Include="ContentManagement\Handlers\StorageVersionFilter.cs" />
<Compile Include="ContentManagement\Handlers\TemplateFilterBase.cs" /> <Compile Include="ContentManagement\Handlers\TemplateFilterBase.cs" />
<Compile Include="ContentManagement\Handlers\TemplateFilterForRecord.cs" /> <Compile Include="ContentManagement\Handlers\TemplateFilterForRecord.cs" />
<Compile Include="ContentManagement\Handlers\UpdateEditorModelContext.cs" /> <Compile Include="ContentManagement\Handlers\UpdateEditorModelContext.cs" />