From 37b270dcab03f15a8bda7fe05253e336fe8af8ae Mon Sep 17 00:00:00 2001 From: loudej Date: Mon, 23 Nov 2009 22:32:43 +0000 Subject: [PATCH] Working on providing support for some common aspects. --HG-- extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4041960 --- .../Models/{BodyPart.cs => BodyAspect.cs} | 2 +- .../Core/Common/Models/BodyPartProvider.cs | 7 -- .../Core/Common/Models/CommonAspect.cs | 37 ++++++++ .../Core/Common/Models/CommonPart.cs | 51 ----------- .../Core/Common/Models/CommonPartProvider.cs | 56 ------------ .../{RoutablePart.cs => RoutableAspect.cs} | 2 +- .../Common/Models/RoutablePartProvider.cs | 11 --- .../Common/Providers/BodyAspectProvider.cs | 7 ++ .../Common/Providers/CommonAspectProvider.cs | 90 +++++++++++++++++++ .../Providers/RoutableAspectProvider.cs | 11 +++ .../Core/Common/Utilities/LazyField.cs | 40 +++++++++ src/Orchard.Web/Core/Orchard.Core.csproj | 13 +-- .../Controllers/PageController.cs | 2 +- .../Models/SandboxContentProvider.cs | 6 +- 14 files changed, 198 insertions(+), 137 deletions(-) rename src/Orchard.Web/Core/Common/Models/{BodyPart.cs => BodyAspect.cs} (70%) delete mode 100644 src/Orchard.Web/Core/Common/Models/BodyPartProvider.cs create mode 100644 src/Orchard.Web/Core/Common/Models/CommonAspect.cs delete mode 100644 src/Orchard.Web/Core/Common/Models/CommonPart.cs delete mode 100644 src/Orchard.Web/Core/Common/Models/CommonPartProvider.cs rename src/Orchard.Web/Core/Common/Models/{RoutablePart.cs => RoutableAspect.cs} (59%) delete mode 100644 src/Orchard.Web/Core/Common/Models/RoutablePartProvider.cs create mode 100644 src/Orchard.Web/Core/Common/Providers/BodyAspectProvider.cs create mode 100644 src/Orchard.Web/Core/Common/Providers/CommonAspectProvider.cs create mode 100644 src/Orchard.Web/Core/Common/Providers/RoutableAspectProvider.cs create mode 100644 src/Orchard.Web/Core/Common/Utilities/LazyField.cs diff --git a/src/Orchard.Web/Core/Common/Models/BodyPart.cs b/src/Orchard.Web/Core/Common/Models/BodyAspect.cs similarity index 70% rename from src/Orchard.Web/Core/Common/Models/BodyPart.cs rename to src/Orchard.Web/Core/Common/Models/BodyAspect.cs index 6ac8c6777..4125ff14e 100644 --- a/src/Orchard.Web/Core/Common/Models/BodyPart.cs +++ b/src/Orchard.Web/Core/Common/Models/BodyAspect.cs @@ -1,7 +1,7 @@ using Orchard.Models; namespace Orchard.Core.Common.Models { - public class BodyPart : Orchard.Models.ContentPart { + public class BodyAspect : ContentPart { public string Body { get; set; } public string Format { get; set; } } diff --git a/src/Orchard.Web/Core/Common/Models/BodyPartProvider.cs b/src/Orchard.Web/Core/Common/Models/BodyPartProvider.cs deleted file mode 100644 index cf4c1e595..000000000 --- a/src/Orchard.Web/Core/Common/Models/BodyPartProvider.cs +++ /dev/null @@ -1,7 +0,0 @@ -using Orchard.Models.Driver; - -namespace Orchard.Core.Common.Models { - public class BodyPartProvider : ContentProvider { - - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Common/Models/CommonAspect.cs b/src/Orchard.Web/Core/Common/Models/CommonAspect.cs new file mode 100644 index 000000000..0fa96e394 --- /dev/null +++ b/src/Orchard.Web/Core/Common/Models/CommonAspect.cs @@ -0,0 +1,37 @@ +using System; +using Orchard.Core.Common.Records; +using Orchard.Core.Common.Utilities; +using Orchard.Models; +using Orchard.Security; + +namespace Orchard.Core.Common.Models { + public class CommonAspect : ContentPart { + private readonly LazyField _owner = new LazyField(); + private readonly LazyField _container = new LazyField(); + + public IUser Owner { + get { return _owner.Value; } + set {_owner.Value = value;} + } + + public IContent Container { + get { return _container.Value; } + set {_container.Value = value;} + } + + internal void OnGetOwner(Func loader) { + _owner.Loader(loader); + } + internal void OnSetOwner(Func setter) { + _owner.Setter(setter); + } + + + internal void OnGetContainer(Func loader) { + _container.Loader(loader); + } + internal void OnSetContainer(Func setter) { + _container.Setter(setter); + } + } +} diff --git a/src/Orchard.Web/Core/Common/Models/CommonPart.cs b/src/Orchard.Web/Core/Common/Models/CommonPart.cs deleted file mode 100644 index 9a0cdcd03..000000000 --- a/src/Orchard.Web/Core/Common/Models/CommonPart.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using Orchard.Core.Common.Records; -using Orchard.Models; -using Orchard.Security; - -namespace Orchard.Core.Common.Models { - public class CommonPart : ContentPart { - private readonly Lazy _owner = new Lazy(); - private readonly Lazy _container = new Lazy(); - - public IUser Owner { - get { return _owner.Value; } - set { _owner.Value = value; } - } - - public IContent Container { - get { return _container.Value; } - set { _container.Value = value; } - } - - public void LoadOwner(Func loader) { - _owner.Loader(loader); - } - public void LoadContainer(Func loader) { - _container.Loader(loader); - } - } - - public class Lazy { - private Func _loader; - private T _value; - - public void Loader(Func loader) { - _loader = loader; - } - - public T Value { - get { - if (_loader != null) { - _value = _loader(); - _loader = null; - } - return _value; - } - set { - _value = value; - _loader = null; - } - } - } -} diff --git a/src/Orchard.Web/Core/Common/Models/CommonPartProvider.cs b/src/Orchard.Web/Core/Common/Models/CommonPartProvider.cs deleted file mode 100644 index 903497430..000000000 --- a/src/Orchard.Web/Core/Common/Models/CommonPartProvider.cs +++ /dev/null @@ -1,56 +0,0 @@ -using Orchard.Core.Common.Records; -using Orchard.Data; -using Orchard.Models; -using Orchard.Models.Driver; -using Orchard.Security; -using Orchard.Services; - -namespace Orchard.Core.Common.Models { - public class CommonPartProvider : ContentProvider { - private readonly IClock _clock; - private readonly IAuthenticationService _authenticationService; - private readonly IContentManager _contentManager; - - public CommonPartProvider( - IRepository repository, - IClock clock, - IAuthenticationService authenticationService, - IContentManager contentManager) { - - _clock = clock; - _authenticationService = authenticationService; - _contentManager = contentManager; - - AddOnCreating(SetCreateTimesAndAuthor); - Filters.Add(new StorageFilter(repository)); - AddOnLoaded(LoadOwnerModel); - } - - void SetCreateTimesAndAuthor(CreateContentContext context, CommonPart instance) { - if (instance.Record.CreatedUtc == null) { - instance.Record.CreatedUtc = _clock.UtcNow; - } - if (instance.Record.ModifiedUtc == null) { - instance.Record.ModifiedUtc = _clock.UtcNow; - } - if (instance.Record.OwnerId == 0) { - instance.Owner = _authenticationService.GetAuthenticatedUser(); - if (instance.Owner != null) - instance.Record.OwnerId = instance.Owner.Id; - } - } - - protected override void UpdateEditors(UpdateContentContext context) { - var part = context.ContentItem.As(); - if (part==null) - return; - - part.Record.ModifiedUtc = _clock.UtcNow; - } - - void LoadOwnerModel(LoadContentContext context, CommonPart part) { - part.LoadOwner(() => _contentManager.Get(part.Record.OwnerId)); - part.LoadContainer(() => part.Record.Container == null ? null : _contentManager.Get(part.Record.Container.Id)); - } - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Common/Models/RoutablePart.cs b/src/Orchard.Web/Core/Common/Models/RoutableAspect.cs similarity index 59% rename from src/Orchard.Web/Core/Common/Models/RoutablePart.cs rename to src/Orchard.Web/Core/Common/Models/RoutableAspect.cs index f21780cff..0ab8ce077 100644 --- a/src/Orchard.Web/Core/Common/Models/RoutablePart.cs +++ b/src/Orchard.Web/Core/Common/Models/RoutableAspect.cs @@ -2,6 +2,6 @@ using Orchard.Core.Common.Records; using Orchard.Models; namespace Orchard.Core.Common.Models { - public class RoutablePart : ContentPart { + public class RoutableAspect : ContentPart { } } \ No newline at end of file diff --git a/src/Orchard.Web/Core/Common/Models/RoutablePartProvider.cs b/src/Orchard.Web/Core/Common/Models/RoutablePartProvider.cs deleted file mode 100644 index 1481cab0a..000000000 --- a/src/Orchard.Web/Core/Common/Models/RoutablePartProvider.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Orchard.Core.Common.Records; -using Orchard.Data; -using Orchard.Models.Driver; - -namespace Orchard.Core.Common.Models { - public class RoutablePartProvider : ContentProvider { - public RoutablePartProvider(IRepository repository) { - Filters.Add(new StorageFilter(repository)); - } - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Common/Providers/BodyAspectProvider.cs b/src/Orchard.Web/Core/Common/Providers/BodyAspectProvider.cs new file mode 100644 index 000000000..b322b929d --- /dev/null +++ b/src/Orchard.Web/Core/Common/Providers/BodyAspectProvider.cs @@ -0,0 +1,7 @@ +using Orchard.Models.Driver; + +namespace Orchard.Core.Common.Providers { + public class BodyAspectProvider : ContentProvider { + + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Common/Providers/CommonAspectProvider.cs b/src/Orchard.Web/Core/Common/Providers/CommonAspectProvider.cs new file mode 100644 index 000000000..6b201ceac --- /dev/null +++ b/src/Orchard.Web/Core/Common/Providers/CommonAspectProvider.cs @@ -0,0 +1,90 @@ +using Orchard.Core.Common.Models; +using Orchard.Core.Common.Records; +using Orchard.Data; +using Orchard.Models; +using Orchard.Models.Driver; +using Orchard.Security; +using Orchard.Services; + +namespace Orchard.Core.Common.Providers { + public class CommonAspectProvider : ContentProvider { + private readonly IClock _clock; + private readonly IAuthenticationService _authenticationService; + private readonly IContentManager _contentManager; + + public CommonAspectProvider( + IRepository repository, + IClock clock, + IAuthenticationService authenticationService, + IContentManager contentManager) { + + _clock = clock; + _authenticationService = authenticationService; + _contentManager = contentManager; + + Filters.Add(new StorageFilter(repository)); + AddOnCreating(DefaultTimestampsAndOwner); + AddOnLoaded(LazyLoadHandlers); + AddOnActivated(PropertySetHandlers); + } + + void DefaultTimestampsAndOwner(CreateContentContext 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; + } + + // and use the current user as Owner + if (instance.Record.OwnerId == 0) { + instance.Owner = _authenticationService.GetAuthenticatedUser(); + if (instance.Owner != null) + instance.Record.OwnerId = instance.Owner.Id; + } + } + + void LazyLoadHandlers(LoadContentContext context, CommonAspect aspect) { + // add handlers that will load content for id's just-in-time + aspect.OwnerField.Loader(() => _contentManager.Get(aspect.Record.OwnerId)); + aspect.ContainerField.Loader(() => aspect.Record.Container == null ? null : _contentManager.Get(aspect.Record.Container.Id)); + } + + static void PropertySetHandlers(ActivatedContentContext context, CommonAspect aspect) { + // add handlers that will update records when aspect properties are set + + aspect.OwnerField.Setter(user => { + if (user == null) { + aspect.Record.OwnerId = 0; + } + else { + aspect.Record.OwnerId = user.ContentItem.Id; + } + return user; + }); + + aspect.ContainerField.Setter(container => { + if (container == null) { + aspect.Record.Container = null; + } + else { + aspect.Record.Container = container.ContentItem.Record; + } + return container; + }); + } + + + protected override void UpdateEditors(UpdateContentContext context) { + var part = context.ContentItem.As(); + if (part == null) + return; + + // 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 + part.Record.ModifiedUtc = _clock.UtcNow; + } + + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Common/Providers/RoutableAspectProvider.cs b/src/Orchard.Web/Core/Common/Providers/RoutableAspectProvider.cs new file mode 100644 index 000000000..bec08bf1e --- /dev/null +++ b/src/Orchard.Web/Core/Common/Providers/RoutableAspectProvider.cs @@ -0,0 +1,11 @@ +using Orchard.Core.Common.Records; +using Orchard.Data; +using Orchard.Models.Driver; + +namespace Orchard.Core.Common.Providers { + public class RoutableAspectProvider : ContentProvider { + public RoutableAspectProvider(IRepository repository) { + Filters.Add(new StorageFilter(repository)); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Common/Utilities/LazyField.cs b/src/Orchard.Web/Core/Common/Utilities/LazyField.cs new file mode 100644 index 000000000..d0d879bcc --- /dev/null +++ b/src/Orchard.Web/Core/Common/Utilities/LazyField.cs @@ -0,0 +1,40 @@ +using System; + +namespace Orchard.Core.Common.Utilities { + public class LazyField { + private T _value; + private Func _loader; + private Func _setter; + + public T Value { + get {return GetValue();} + set {SetValue(value);} + } + + public void Loader(Func loader) { + _loader = loader; + } + + public void Setter(Func setter) { + _setter = setter; + } + + private T GetValue() { + if (_loader != null) { + _value = _loader(); + _loader = null; + } + return _value; + } + + private void SetValue(T value) { + _loader = null; + if (_setter != null) { + _value = _setter(value); + } + else { + _value = value; + } + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Orchard.Core.csproj b/src/Orchard.Web/Core/Orchard.Core.csproj index fa4593edc..b0658f567 100644 --- a/src/Orchard.Web/Core/Orchard.Core.csproj +++ b/src/Orchard.Web/Core/Orchard.Core.csproj @@ -61,12 +61,13 @@ - - - - - - + + + + + + + diff --git a/src/Orchard.Web/Packages/Orchard.Sandbox/Controllers/PageController.cs b/src/Orchard.Web/Packages/Orchard.Sandbox/Controllers/PageController.cs index 70f1ea73c..2be952f1c 100644 --- a/src/Orchard.Web/Packages/Orchard.Sandbox/Controllers/PageController.cs +++ b/src/Orchard.Web/Packages/Orchard.Sandbox/Controllers/PageController.cs @@ -47,7 +47,7 @@ namespace Orchard.Sandbox.Controllers public ActionResult Create(PageCreateViewModel model) { var page = _contentManager.Create("sandboxpage", item => { item.Record.Name = model.Name; - item.As().Container = CurrentSite.ContentItem; + item.As().Container = CurrentSite.ContentItem; }); return RedirectToAction("show", new { page.ContentItem.Id }); } diff --git a/src/Orchard.Web/Packages/Orchard.Sandbox/Models/SandboxContentProvider.cs b/src/Orchard.Web/Packages/Orchard.Sandbox/Models/SandboxContentProvider.cs index 0133d2315..1ddb3580b 100644 --- a/src/Orchard.Web/Packages/Orchard.Sandbox/Models/SandboxContentProvider.cs +++ b/src/Orchard.Web/Packages/Orchard.Sandbox/Models/SandboxContentProvider.cs @@ -11,9 +11,9 @@ namespace Orchard.Sandbox.Models { // define the "sandboxpage" content type Filters.Add(new ActivatingFilter("sandboxpage")); - Filters.Add(new ActivatingFilter("sandboxpage")); - Filters.Add(new ActivatingFilter("sandboxpage")); - Filters.Add(new ActivatingFilter("sandboxpage")); + Filters.Add(new ActivatingFilter("sandboxpage")); + Filters.Add(new ActivatingFilter("sandboxpage")); + Filters.Add(new ActivatingFilter("sandboxpage")); Filters.Add(new StorageFilter(pageRepository) { AutomaticallyCreateMissingRecord = true }); // add settings to site, and simple record-template gui