diff --git a/src/Orchard.Core.Tests/Common/Providers/CommonAspectProviderTests.cs b/src/Orchard.Core.Tests/Common/Providers/CommonAspectProviderTests.cs index d62bae234..73cbde057 100644 --- a/src/Orchard.Core.Tests/Common/Providers/CommonAspectProviderTests.cs +++ b/src/Orchard.Core.Tests/Common/Providers/CommonAspectProviderTests.cs @@ -6,7 +6,6 @@ using JetBrains.Annotations; using Moq; using NUnit.Framework; using Orchard.ContentManagement.Aspects; -using Orchard.ContentManagement.MetaData.Records; using Orchard.Core.Common; using Orchard.Core.Common.Handlers; using Orchard.Core.Common.Models; @@ -47,8 +46,6 @@ namespace Orchard.Core.Tests.Common.Providers { get { return new[] { typeof(ContentTypeRecord), - typeof(ContentTypePartRecord), - typeof(ContentTypePartNameRecord), typeof(ContentItemRecord), typeof(ContentItemVersionRecord), typeof(CommonRecord), diff --git a/src/Orchard.Core.Tests/Common/Services/RoutableServiceTests.cs b/src/Orchard.Core.Tests/Common/Services/RoutableServiceTests.cs index 69bb981db..695589dbb 100644 --- a/src/Orchard.Core.Tests/Common/Services/RoutableServiceTests.cs +++ b/src/Orchard.Core.Tests/Common/Services/RoutableServiceTests.cs @@ -6,7 +6,6 @@ using NUnit.Framework; using Orchard.ContentManagement; using Orchard.ContentManagement.Drivers; using Orchard.ContentManagement.Handlers; -using Orchard.ContentManagement.MetaData.Records; using Orchard.ContentManagement.Records; using Orchard.Core.Common.Models; using Orchard.Core.Common.Services; @@ -182,8 +181,6 @@ namespace Orchard.Core.Tests.Common.Services { return new[] { typeof(RoutableRecord), typeof(ContentTypeRecord), - typeof(ContentTypePartRecord), - typeof(ContentTypePartNameRecord), typeof(ContentItemRecord), typeof(ContentItemVersionRecord), typeof(CommonRecord), diff --git a/src/Orchard.Core.Tests/Orchard.Core.Tests.csproj b/src/Orchard.Core.Tests/Orchard.Core.Tests.csproj index 307f9ed26..1d07df81b 100644 --- a/src/Orchard.Core.Tests/Orchard.Core.Tests.csproj +++ b/src/Orchard.Core.Tests/Orchard.Core.Tests.csproj @@ -109,6 +109,7 @@ + diff --git a/src/Orchard.Core.Tests/Scheduling/ScheduledTaskExecutorTests.cs b/src/Orchard.Core.Tests/Scheduling/ScheduledTaskExecutorTests.cs index e7a7955dd..cf3d73786 100644 --- a/src/Orchard.Core.Tests/Scheduling/ScheduledTaskExecutorTests.cs +++ b/src/Orchard.Core.Tests/Scheduling/ScheduledTaskExecutorTests.cs @@ -4,7 +4,6 @@ using Autofac; using Moq; using NUnit.Framework; using Orchard.ContentManagement; -using Orchard.ContentManagement.MetaData.Records; using Orchard.ContentManagement.Records; using Orchard.Core.Scheduling.Models; using Orchard.Core.Scheduling.Services; @@ -39,8 +38,6 @@ namespace Orchard.Core.Tests.Scheduling { get { return new[] { typeof(ContentTypeRecord), - typeof(ContentTypePartRecord), - typeof(ContentTypePartNameRecord), typeof(ContentItemRecord), typeof(ContentItemVersionRecord), typeof(ScheduledTaskRecord), diff --git a/src/Orchard.Core.Tests/Scheduling/ScheduledTaskManagerTests.cs b/src/Orchard.Core.Tests/Scheduling/ScheduledTaskManagerTests.cs index baf3063c3..fe58b9a06 100644 --- a/src/Orchard.Core.Tests/Scheduling/ScheduledTaskManagerTests.cs +++ b/src/Orchard.Core.Tests/Scheduling/ScheduledTaskManagerTests.cs @@ -5,7 +5,6 @@ using Autofac; using Moq; using NUnit.Framework; using Orchard.ContentManagement; -using Orchard.ContentManagement.MetaData.Records; using Orchard.ContentManagement.Records; using Orchard.Core.Scheduling.Models; using Orchard.Core.Scheduling.Services; @@ -42,8 +41,6 @@ namespace Orchard.Core.Tests.Scheduling { get { return new[] { typeof(ContentTypeRecord), - typeof(ContentTypePartRecord), - typeof(ContentTypePartNameRecord), typeof(ContentItemRecord), typeof(ContentItemVersionRecord), typeof(ScheduledTaskRecord), diff --git a/src/Orchard.Core.Tests/Settings/Metadata/ContentDefinitionManagerTests.cs b/src/Orchard.Core.Tests/Settings/Metadata/ContentDefinitionManagerTests.cs new file mode 100644 index 000000000..440c38864 --- /dev/null +++ b/src/Orchard.Core.Tests/Settings/Metadata/ContentDefinitionManagerTests.cs @@ -0,0 +1,211 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Xml.Linq; +using Autofac; +using Moq; +using NHibernate; +using NUnit.Framework; +using Orchard.ContentManagement.MetaData; +using Orchard.ContentManagement.MetaData.Builders; +using Orchard.ContentManagement.MetaData.Models; +using Orchard.ContentManagement.MetaData.Services; +using Orchard.Core.Settings.Metadata; +using Orchard.Core.Settings.Metadata.Records; +using Orchard.Data; +using Orchard.Tests; +using Orchard.Tests.Utility; + +namespace Orchard.Core.Tests.Settings.Metadata { + [TestFixture] + public class ContentDefinitionManagerTests { + private string _databaseFileName; + private ISessionFactory _sessionFactory; + private ISession _session; + private IContainer _container; + + [TestFixtureSetUp] + public void InitFixture() { + _databaseFileName = Path.GetTempFileName(); + _sessionFactory = DataUtility.CreateSessionFactory( + _databaseFileName, + typeof(ContentTypeDefinitionRecord), + typeof(ContentTypePartDefinitionRecord), + typeof(ContentPartDefinitionRecord), + typeof(ContentPartFieldDefinitionRecord), + typeof(ContentFieldDefinitionRecord) + ); + } + + [SetUp] + public void Init() { + var builder = new ContainerBuilder(); + builder.RegisterAutoMocking(); + builder.RegisterType().As(); + builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)); + builder.RegisterType(typeof(SettingsFormatter)) + .As(typeof(IMapper>)) + .As(typeof(IMapper, XElement>)); + _container = builder.Build(); + + _container.Mock() + .Setup(x => x.For(It.IsAny())) + .Returns(() => _session); + + _session = _sessionFactory.OpenSession(); + foreach (var killType in new[] { typeof(ContentTypeDefinitionRecord), typeof(ContentPartDefinitionRecord), typeof(ContentFieldDefinitionRecord) }) { + foreach (var killRecord in _session.CreateCriteria(killType).List()) { + _session.Delete(killRecord); + } + } + _session.Flush(); + } + + void ResetSession() { + _session.Flush(); + _session.Dispose(); + _session = _sessionFactory.OpenSession(); + } + + [TearDown] + public void Term() { + _session.Dispose(); + } + + [TestFixtureTearDown] + public void TermFixture() { + File.Delete(_databaseFileName); + } + + [Test] + public void NoTypesAreAvailableByDefault() { + var types = _container.Resolve().ListTypeDefinitions(); + Assert.That(types.Count(), Is.EqualTo(0)); + } + + [Test] + public void TypeRecordsAreReturned() { + var repository = _container.Resolve>(); + repository.Create(new ContentTypeDefinitionRecord { Name = "alpha" }); + repository.Create(new ContentTypeDefinitionRecord { Name = "beta" }); + ResetSession(); + var types = _container.Resolve().ListTypeDefinitions(); + Assert.That(types.Count(), Is.EqualTo(2)); + } + + [Test] + public void TypeSettingsAreParsed() { + var repository = _container.Resolve>(); + repository.Create(new ContentTypeDefinitionRecord { Name = "alpha", Settings = "" }); + ResetSession(); + var alpha = _container.Resolve().ListTypeDefinitions().Single(); + Assert.That(alpha.Settings["a"], Is.EqualTo("1")); + Assert.That(alpha.Settings["b"], Is.EqualTo("2")); + } + + [Test] + public void ContentTypesWithSettingsCanBeCreatedAndModified() { + var manager = _container.Resolve(); + manager.StoreTypeDefinition(new ContentTypeDefinitionBuilder() + .Named("alpha") + .WithSetting("a", "1") + .WithSetting("b", "2") + .Build()); + + manager.StoreTypeDefinition(new ContentTypeDefinitionBuilder() + .Named("beta") + .WithSetting("c", "3") + .WithSetting("d", "4") + .Build()); + + ResetSession(); + + var types1 = manager.ListTypeDefinitions(); + Assert.That(types1.Count(), Is.EqualTo(2)); + var alpha1 = types1.Single(t => t.Name == "alpha"); + Assert.That(alpha1.Settings["a"], Is.EqualTo("1")); + manager.StoreTypeDefinition(new ContentTypeDefinitionBuilder(alpha1).WithSetting("a", "5").Build()); + ResetSession(); + + var types2 = manager.ListTypeDefinitions(); + Assert.That(types2.Count(), Is.EqualTo(2)); + var alpha2 = types2.Single(t => t.Name == "alpha"); + Assert.That(alpha2.Settings["a"], Is.EqualTo("5")); + Assert.That(alpha2.Settings["a"], Is.EqualTo("5")); + } + + [Test] + public void StubPartDefinitionsAreCreatedWhenContentTypesAreStored() { + var manager = _container.Resolve(); + manager.StoreTypeDefinition(new ContentTypeDefinitionBuilder() + .Named("alpha") + .WithPart("foo", pb => { }) + .Build()); + + ResetSession(); + + var fooRecord = _container.Resolve>().Fetch(r => r.Name == "foo").SingleOrDefault(); + Assert.That(fooRecord, Is.Not.Null); + Assert.That(fooRecord.Name, Is.EqualTo("foo")); + + var foo = manager.GetPartDefinition("foo"); + Assert.That(foo, Is.Not.Null); + Assert.That(foo.Name, Is.EqualTo("foo")); + + var alpha = manager.GetTypeDefinition("alpha"); + Assert.That(alpha, Is.Not.Null); + Assert.That(alpha.Parts.Count(), Is.EqualTo(1)); + Assert.That(alpha.Parts.Single().PartDefinition.Name, Is.EqualTo("foo")); + } + + [Test] + public void GettingDefinitionsByNameCanReturnNullAndWillAcceptNullEmptyOrInvalidNames() { + var manager = _container.Resolve(); + Assert.That(manager.GetTypeDefinition("no such name"), Is.Null); + Assert.That(manager.GetTypeDefinition(string.Empty), Is.Null); + Assert.That(manager.GetTypeDefinition(null), Is.Null); + Assert.That(manager.GetPartDefinition("no such name"), Is.Null); + Assert.That(manager.GetPartDefinition(string.Empty), Is.Null); + Assert.That(manager.GetPartDefinition(null), Is.Null); + } + + [Test] + public void PartsAreRemovedWhenNotReferencedButPartDefinitionRemains() { + var manager = _container.Resolve(); + manager.StoreTypeDefinition( + new ContentTypeDefinitionBuilder() + .Named("alpha") + .WithPart("foo", pb => { }) + .WithPart("bar", pb => { }) + .Build()); + + AssertThatTypeHasParts("alpha","foo","bar"); + Assert.That(manager.ListPartDefinitions().Count(), Is.EqualTo(2)); + ResetSession(); + AssertThatTypeHasParts("alpha","foo","bar"); + Assert.That(manager.ListPartDefinitions().Count(), Is.EqualTo(2)); + + manager.StoreTypeDefinition( + new ContentTypeDefinitionBuilder(manager.GetTypeDefinition("alpha")) + .WithPart("frap", pb => { }) + .RemovePart("bar") + .Build()); + + AssertThatTypeHasParts("alpha","foo","frap"); + Assert.That(manager.ListPartDefinitions().Count(), Is.EqualTo(3)); + ResetSession(); + AssertThatTypeHasParts("alpha","foo","frap"); + Assert.That(manager.ListPartDefinitions().Count(), Is.EqualTo(3)); + } + + private void AssertThatTypeHasParts(string typeName, params string[] partNames) { + var type = _container.Resolve().GetTypeDefinition(typeName); + Assert.That(type, Is.Not.Null); + Assert.That(type.Parts.Count(), Is.EqualTo(partNames.Count())); + foreach(var partName in partNames) { + Assert.That(type.Parts.Select(p=>p.PartDefinition.Name), Has.Some.EqualTo(partName)); + } + } + } +} diff --git a/src/Orchard.Tests.Modules/Users/Controllers/AdminControllerTests.cs b/src/Orchard.Tests.Modules/Users/Controllers/AdminControllerTests.cs index 54dfd37f3..5b1f3a49f 100644 --- a/src/Orchard.Tests.Modules/Users/Controllers/AdminControllerTests.cs +++ b/src/Orchard.Tests.Modules/Users/Controllers/AdminControllerTests.cs @@ -6,7 +6,6 @@ using System.Web.Routing; using Autofac; using Moq; using NUnit.Framework; -using Orchard.ContentManagement.MetaData.Records; using Orchard.Data; using Orchard.Environment; using Orchard.ContentManagement; @@ -47,8 +46,6 @@ namespace Orchard.Tests.Modules.Users.Controllers { get { return new[] { typeof(UserRecord), typeof(ContentTypeRecord), - typeof(ContentTypePartRecord), - typeof(ContentTypePartNameRecord), typeof(ContentItemRecord), typeof(ContentItemVersionRecord), }; diff --git a/src/Orchard.Tests.Modules/Users/Services/MembershipServiceTests.cs b/src/Orchard.Tests.Modules/Users/Services/MembershipServiceTests.cs index 81551167c..ea7ee2f3d 100644 --- a/src/Orchard.Tests.Modules/Users/Services/MembershipServiceTests.cs +++ b/src/Orchard.Tests.Modules/Users/Services/MembershipServiceTests.cs @@ -3,7 +3,6 @@ using System.Web.Security; using Autofac; using NHibernate; using NUnit.Framework; -using Orchard.ContentManagement.MetaData.Records; using Orchard.Data; using Orchard.ContentManagement; using Orchard.ContentManagement.Handlers; @@ -42,9 +41,7 @@ namespace Orchard.Tests.Modules.Users.Services { typeof(UserRecord), typeof(ContentItemVersionRecord), typeof(ContentItemRecord), - typeof(ContentTypeRecord), - typeof(ContentTypePartRecord), - typeof(ContentTypePartNameRecord)); + typeof(ContentTypeRecord)); } [TestFixtureTearDown] diff --git a/src/Orchard.Tests/ContentManagement/ContentQueryTests.cs b/src/Orchard.Tests/ContentManagement/ContentQueryTests.cs index 55d9960e5..8b37ebe65 100644 --- a/src/Orchard.Tests/ContentManagement/ContentQueryTests.cs +++ b/src/Orchard.Tests/ContentManagement/ContentQueryTests.cs @@ -2,7 +2,6 @@ using Autofac; using NHibernate; using NUnit.Framework; -using Orchard.ContentManagement.MetaData.Records; using Orchard.Data; using Orchard.ContentManagement; using Orchard.ContentManagement.Handlers; @@ -28,9 +27,7 @@ namespace Orchard.Tests.ContentManagement { typeof(EpsilonRecord), typeof(ContentItemVersionRecord), typeof(ContentItemRecord), - typeof(ContentTypeRecord), - typeof(ContentTypePartRecord), - typeof(ContentTypePartNameRecord)); + typeof(ContentTypeRecord)); } [TestFixtureTearDown] diff --git a/src/Orchard.Tests/ContentManagement/ContentTypeMetaDataTests.cs b/src/Orchard.Tests/ContentManagement/ContentTypeMetaDataTests.cs deleted file mode 100644 index 94a31ebba..000000000 --- a/src/Orchard.Tests/ContentManagement/ContentTypeMetaDataTests.cs +++ /dev/null @@ -1,62 +0,0 @@ -using Autofac; -using NHibernate; -using NUnit.Framework; -using Orchard.ContentManagement; -using Orchard.ContentManagement.MetaData.Records; -using Orchard.ContentManagement.MetaData.Services; -using Orchard.ContentManagement.Records; -using Orchard.Data; - - -namespace Orchard.Tests.ContentManagement{ - [TestFixture] - public class ContentTypeMetaDataTests - { - private IContainer _container; - private ISessionFactory _sessionFactory; - private ISession _session; - - [TestFixtureSetUp] - public void InitFixture() - { - var databaseFileName = System.IO.Path.GetTempFileName(); - _sessionFactory = DataUtility.CreateSessionFactory( - databaseFileName, - typeof(ContentTypeRecord), - typeof(ContentItemRecord), - typeof(ContentTypePartRecord), - typeof(ContentTypePartNameRecord), - typeof(ContentItemVersionRecord)); - } - - [TestFixtureTearDown] - public void TermFixture() - { - - } - - [SetUp] - public void Init() - { - var builder = new ContainerBuilder(); - builder.RegisterType().As(); - builder.RegisterType().As(); - builder.RegisterType().As(); - builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)); - _session = _sessionFactory.OpenSession(); - builder.RegisterInstance(new DefaultContentManagerTests.TestSessionLocator(_session)).As(); - - _container = builder.Build(); - } - - [Test] - public void MapandUnMapContentTypeToContentPart() - { - var contentTypeService = _container.Resolve(); - contentTypeService.MapContentTypeToContentPart("foo", "bar"); - Assert.IsTrue(contentTypeService.ValidateContentTypeToContentPartMapping("foo","bar"),"Content Type not successfully mapped"); - contentTypeService.UnMapContentTypeToContentPart("foo", "bar"); - Assert.IsFalse(contentTypeService.ValidateContentTypeToContentPartMapping("foo", "bar"), "Content Type mapping not successfully deleted"); - } - } -} diff --git a/src/Orchard.Tests/ContentManagement/DefaultContentManagerTests.cs b/src/Orchard.Tests/ContentManagement/DefaultContentManagerTests.cs index 6341d4f4c..36de12e5d 100644 --- a/src/Orchard.Tests/ContentManagement/DefaultContentManagerTests.cs +++ b/src/Orchard.Tests/ContentManagement/DefaultContentManagerTests.cs @@ -4,7 +4,6 @@ using System.Linq; using Autofac; using NHibernate; using NUnit.Framework; -using Orchard.ContentManagement.MetaData.Records; using Orchard.Data; using Orchard.ContentManagement; using Orchard.ContentManagement.Handlers; @@ -26,8 +25,6 @@ namespace Orchard.Tests.ContentManagement { _sessionFactory = DataUtility.CreateSessionFactory( databaseFileName, typeof(ContentTypeRecord), - typeof(ContentTypePartRecord), - typeof(ContentTypePartNameRecord), typeof(ContentItemRecord), typeof(ContentItemVersionRecord), typeof(GammaRecord), diff --git a/src/Orchard.Tests/ContentManagement/MetaData/Builders/ContentTypeDefinitionBuilderTests.cs b/src/Orchard.Tests/ContentManagement/MetaData/Builders/ContentTypeDefinitionBuilderTests.cs new file mode 100644 index 000000000..be8549f18 --- /dev/null +++ b/src/Orchard.Tests/ContentManagement/MetaData/Builders/ContentTypeDefinitionBuilderTests.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using Orchard.ContentManagement.MetaData.Builders; + +namespace Orchard.Tests.ContentManagement.MetaData.Builders { + [TestFixture] + public class ContentTypeDefinitionBuilderTests { + [Test] + public void ContentTypeNameAndSettingsFromScratch() { + var contentTypeDefinition = new ContentTypeDefinitionBuilder() + .Named("alpha") + .WithSetting("a", "1") + .WithSetting("b", "2") + .Build(); + Assert.That(contentTypeDefinition.Name, Is.EqualTo("alpha")); + Assert.That(contentTypeDefinition.Settings.Count(), Is.EqualTo(2)); + Assert.That(contentTypeDefinition.Settings["a"], Is.EqualTo("1")); + Assert.That(contentTypeDefinition.Settings["b"], Is.EqualTo("2")); + } + + [Test] + public void ContentRebuildWithoutModification() { + var contentTypeDefinition1 = new ContentTypeDefinitionBuilder() + .Named("alpha") + .WithSetting("a", "1") + .WithSetting("b", "2") + .Build(); + var contentTypeDefinition2 = new ContentTypeDefinitionBuilder(contentTypeDefinition1) + .Build(); + Assert.That(contentTypeDefinition1, Is.Not.SameAs(contentTypeDefinition2)); + Assert.That(contentTypeDefinition2.Name, Is.EqualTo("alpha")); + Assert.That(contentTypeDefinition2.Settings.Count(), Is.EqualTo(2)); + Assert.That(contentTypeDefinition2.Settings["a"], Is.EqualTo("1")); + Assert.That(contentTypeDefinition2.Settings["b"], Is.EqualTo("2")); + } + + [Test] + public void ContentRebuildWithModification() { + var contentTypeDefinition1 = new ContentTypeDefinitionBuilder() + .Named("alpha") + .WithSetting("a", "1") + .WithSetting("b", "2") + .Build(); + var contentTypeDefinition2 = new ContentTypeDefinitionBuilder(contentTypeDefinition1) + .Named("beta") + .WithSetting("b", "22") + .WithSetting("c", "3") + .Build(); + Assert.That(contentTypeDefinition1, Is.Not.SameAs(contentTypeDefinition2)); + Assert.That(contentTypeDefinition1.Name, Is.EqualTo("alpha")); + Assert.That(contentTypeDefinition1.Settings.Count(), Is.EqualTo(2)); + Assert.That(contentTypeDefinition1.Settings["a"], Is.EqualTo("1")); + Assert.That(contentTypeDefinition1.Settings["b"], Is.EqualTo("2")); + Assert.That(contentTypeDefinition2.Name, Is.EqualTo("beta")); + Assert.That(contentTypeDefinition2.Settings.Count(), Is.EqualTo(3)); + Assert.That(contentTypeDefinition2.Settings["a"], Is.EqualTo("1")); + Assert.That(contentTypeDefinition2.Settings["b"], Is.EqualTo("22")); + Assert.That(contentTypeDefinition2.Settings["c"], Is.EqualTo("3")); + } + + [Test] + public void AddingPartWithSettings() { + var contentTypeDefinition = new ContentTypeDefinitionBuilder() + .Named("alpha") + .WithSetting("a", "1") + .WithSetting("b", "2") + .WithPart("foo", pb => pb.WithSetting("x", "10").WithSetting("y", "11")) + .Build(); + + Assert.That(contentTypeDefinition.Name, Is.EqualTo("alpha")); + Assert.That(contentTypeDefinition.Parts.Count(), Is.EqualTo(1)); + Assert.That(contentTypeDefinition.Parts.Single().PartDefinition.Name, Is.EqualTo("foo")); + Assert.That(contentTypeDefinition.Parts.Single().Settings.Count(), Is.EqualTo(2)); + Assert.That(contentTypeDefinition.Parts.Single().Settings["x"], Is.EqualTo("10")); + Assert.That(contentTypeDefinition.Parts.Single().Settings["y"], Is.EqualTo("11")); + } + + [Test] + public void CanAlterPartSettingsByNameDuringBuild() { + var contentTypeDefinition = new ContentTypeDefinitionBuilder() + .Named("alpha") + .WithSetting("a", "1") + .WithSetting("b", "2") + .WithPart("foo", pb => pb.WithSetting("x", "10")) + .WithPart("foo", pb => pb.WithSetting("y", "11")) + .Build(); + + Assert.That(contentTypeDefinition.Name, Is.EqualTo("alpha")); + Assert.That(contentTypeDefinition.Parts.Count(), Is.EqualTo(1)); + Assert.That(contentTypeDefinition.Parts.Single().PartDefinition.Name, Is.EqualTo("foo")); + Assert.That(contentTypeDefinition.Parts.Single().Settings.Count(), Is.EqualTo(2)); + Assert.That(contentTypeDefinition.Parts.Single().Settings["x"], Is.EqualTo("10")); + Assert.That(contentTypeDefinition.Parts.Single().Settings["y"], Is.EqualTo("11")); + } + + [Test] + public void CanAlterPartSettingsByNameDuringRebuild() { + var contentTypeDefinition1 = new ContentTypeDefinitionBuilder() + .Named("alpha") + .WithPart("foo", pb => pb.WithSetting("x", "10").WithSetting("y", "11")) + .Build(); + + var contentTypeDefinition2 = new ContentTypeDefinitionBuilder(contentTypeDefinition1) + .WithPart("foo", pb => pb.WithSetting("x", "12").WithSetting("z", "13")) + .Build(); + + Assert.That(contentTypeDefinition1.Name, Is.EqualTo("alpha")); + Assert.That(contentTypeDefinition1.Parts.Count(), Is.EqualTo(1)); + Assert.That(contentTypeDefinition1.Parts.Single().PartDefinition.Name, Is.EqualTo("foo")); + Assert.That(contentTypeDefinition1.Parts.Single().Settings.Count(), Is.EqualTo(2)); + Assert.That(contentTypeDefinition1.Parts.Single().Settings["x"], Is.EqualTo("10")); + Assert.That(contentTypeDefinition1.Parts.Single().Settings["y"], Is.EqualTo("11")); + Assert.That(contentTypeDefinition2.Name, Is.EqualTo("alpha")); + Assert.That(contentTypeDefinition2.Parts.Count(), Is.EqualTo(1)); + Assert.That(contentTypeDefinition2.Parts.Single().PartDefinition.Name, Is.EqualTo("foo")); + Assert.That(contentTypeDefinition2.Parts.Single().Settings.Count(), Is.EqualTo(3)); + Assert.That(contentTypeDefinition2.Parts.Single().Settings["x"], Is.EqualTo("12")); + Assert.That(contentTypeDefinition2.Parts.Single().Settings["y"], Is.EqualTo("11")); + Assert.That(contentTypeDefinition2.Parts.Single().Settings["z"], Is.EqualTo("13")); + } + + [Test, IgnoreAttribute("Merging not yet implemented")] + public void ContentMergeOverlaysSettings() { + Assert.Fail(); + } + } +} diff --git a/src/Orchard.Tests/Orchard.Framework.Tests.csproj b/src/Orchard.Tests/Orchard.Framework.Tests.csproj index 258137642..5d469d06c 100644 --- a/src/Orchard.Tests/Orchard.Framework.Tests.csproj +++ b/src/Orchard.Tests/Orchard.Framework.Tests.csproj @@ -148,12 +148,12 @@ Code - Code + diff --git a/src/Orchard.Web/Core/Orchard.Core.csproj b/src/Orchard.Web/Core/Orchard.Core.csproj index b7d14d395..b29aa2515 100644 --- a/src/Orchard.Web/Core/Orchard.Core.csproj +++ b/src/Orchard.Web/Core/Orchard.Core.csproj @@ -143,6 +143,12 @@ + + + + + + diff --git a/src/Orchard.Web/Core/Settings/Metadata/ContentDefinitionManager.cs b/src/Orchard.Web/Core/Settings/Metadata/ContentDefinitionManager.cs new file mode 100644 index 000000000..c3be204ac --- /dev/null +++ b/src/Orchard.Web/Core/Settings/Metadata/ContentDefinitionManager.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Xml.Linq; +using Orchard.ContentManagement.MetaData; +using Orchard.ContentManagement.MetaData.Models; +using Orchard.Core.Settings.Metadata.Records; +using Orchard.Data; +using Orchard.Logging; +using Orchard.Utility.Extensions; + +namespace Orchard.Core.Settings.Metadata { + public class ContentDefinitionManager : Component, IContentDefinitionManager { + private readonly IRepository _typeDefinitionRepository; + private readonly IRepository _partDefinitionRepository; + private readonly IMapper> _settingsReader; + private readonly IMapper, XElement> _settingsWriter; + + public ContentDefinitionManager( + IRepository typeDefinitionRepository, + IRepository partDefinitionRepository, + IMapper> settingsReader, + IMapper, XElement> settingsWriter) { + _typeDefinitionRepository = typeDefinitionRepository; + _partDefinitionRepository = partDefinitionRepository; + _settingsReader = settingsReader; + _settingsWriter = settingsWriter; + } + + public ContentTypeDefinition GetTypeDefinition(string name) { + return _typeDefinitionRepository.Fetch(x => x.Name == name).Select(Build).SingleOrDefault(); + } + + public ContentPartDefinition GetPartDefinition(string name) { + return _partDefinitionRepository.Fetch(x => x.Name == name).Select(Build).SingleOrDefault(); + } + + public IEnumerable ListTypeDefinitions() { + return _typeDefinitionRepository.Fetch(x => !x.Hidden).Select(Build).ToReadOnlyCollection(); + } + + public IEnumerable ListPartDefinitions() { + return _partDefinitionRepository.Fetch(x => !x.Hidden).Select(Build).ToReadOnlyCollection(); + } + + public void StoreTypeDefinition(ContentTypeDefinition contentTypeDefinition) { + Apply(contentTypeDefinition, Acquire(contentTypeDefinition)); + } + + public void StorePartDefinition(ContentPartDefinition contentPartDefinition) { + throw new NotImplementedException(); + } + + private ContentTypeDefinitionRecord Acquire(ContentTypeDefinition contentTypeDefinition) { + var result = _typeDefinitionRepository.Fetch(x => x.Name == contentTypeDefinition.Name).SingleOrDefault(); + if (result == null) { + result = new ContentTypeDefinitionRecord { Name = contentTypeDefinition.Name }; + _typeDefinitionRepository.Create(result); + } + return result; + } + + private ContentPartDefinitionRecord Acquire(ContentPartDefinition contentPartDefinition) { + var result = _partDefinitionRepository.Fetch(x => x.Name == contentPartDefinition.Name).SingleOrDefault(); + if (result == null) { + result = new ContentPartDefinitionRecord { Name = contentPartDefinition.Name }; + _partDefinitionRepository.Create(result); + } + return result; + } + + private void Apply(ContentTypeDefinition model, ContentTypeDefinitionRecord record) { + record.Settings = _settingsWriter.Map(model.Settings).ToString(); + + var toRemove = record.ContentTypePartDefinitionRecords + .Where(partDefinitionRecord => !model.Parts.Any(part => partDefinitionRecord.ContentPartDefinitionRecord.Name == part.PartDefinition.Name)) + .ToList(); + + foreach (var remove in toRemove) { + record.ContentTypePartDefinitionRecords.Remove(remove); + } + + foreach (var part in model.Parts) { + var partName = part.PartDefinition.Name; + var typePartRecord = record.ContentTypePartDefinitionRecords.SingleOrDefault(r => r.ContentPartDefinitionRecord.Name == partName); + if (typePartRecord == null) { + typePartRecord = new ContentTypePartDefinitionRecord { ContentPartDefinitionRecord = Acquire(part.PartDefinition) }; + record.ContentTypePartDefinitionRecords.Add(typePartRecord); + } + Apply(part, typePartRecord); + } + } + + private void Apply(ContentTypeDefinition.Part model, ContentTypePartDefinitionRecord record) { + record.Settings = Compose(_settingsWriter.Map(model.Settings)); + } + + + + ContentTypeDefinition Build(ContentTypeDefinitionRecord source) { + return new ContentTypeDefinition( + source.Name, + source.ContentTypePartDefinitionRecords.Select(Build), + _settingsReader.Map(Parse(source.Settings))); + } + + ContentTypeDefinition.Part Build(ContentTypePartDefinitionRecord source) { + return new ContentTypeDefinition.Part( + Build(source.ContentPartDefinitionRecord), + _settingsReader.Map(Parse(source.Settings))); + } + + ContentPartDefinition Build(ContentPartDefinitionRecord source) { + return new ContentPartDefinition( + source.Name, + source.ContentPartFieldDefinitionRecords.Select(Build), + _settingsReader.Map(Parse(source.Settings))); + } + + ContentPartDefinition.Field Build(ContentPartFieldDefinitionRecord source) { + return new ContentPartDefinition.Field( + Build(source.ContentFieldDefinitionRecord), + source.Name, + _settingsReader.Map(Parse(source.Settings))); + } + + ContentFieldDefinition Build(ContentFieldDefinitionRecord source) { + return new ContentFieldDefinition(source.Name); + } + + XElement Parse(string settings) { + if (string.IsNullOrEmpty(settings)) + return null; + + try { + return XElement.Parse(settings); + } + catch (Exception ex) { + Logger.Error(ex, "Unable to parse settings xml"); + return null; + } + } + string Compose(XElement map) { + if (map == null) + return null; + + return map.ToString(); + } + } +} diff --git a/src/Orchard.Web/Core/Settings/Metadata/Records/ContentFieldDefinitionRecord.cs b/src/Orchard.Web/Core/Settings/Metadata/Records/ContentFieldDefinitionRecord.cs new file mode 100644 index 000000000..a8cf97aff --- /dev/null +++ b/src/Orchard.Web/Core/Settings/Metadata/Records/ContentFieldDefinitionRecord.cs @@ -0,0 +1,6 @@ +namespace Orchard.Core.Settings.Metadata.Records { + public class ContentFieldDefinitionRecord { + public virtual int Id { get; set; } + public virtual string Name { get; set; } + } +} diff --git a/src/Orchard.Web/Core/Settings/Metadata/Records/ContentPartDefinitionRecord.cs b/src/Orchard.Web/Core/Settings/Metadata/Records/ContentPartDefinitionRecord.cs new file mode 100644 index 000000000..76045f25b --- /dev/null +++ b/src/Orchard.Web/Core/Settings/Metadata/Records/ContentPartDefinitionRecord.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using Orchard.Data.Conventions; + +namespace Orchard.Core.Settings.Metadata.Records { + public class ContentPartDefinitionRecord { + public ContentPartDefinitionRecord() { + ContentPartFieldDefinitionRecords = new List(); + } + + public virtual int Id { get; set; } + public virtual string Name { get; set; } + public virtual bool Hidden { get; set; } + public virtual string Settings { get; set; } + + [CascadeAllDeleteOrphan] + public virtual IList ContentPartFieldDefinitionRecords { get; set; } + + } +} diff --git a/src/Orchard.Web/Core/Settings/Metadata/Records/ContentPartFieldDefinitionRecord.cs b/src/Orchard.Web/Core/Settings/Metadata/Records/ContentPartFieldDefinitionRecord.cs new file mode 100644 index 000000000..f85da77d0 --- /dev/null +++ b/src/Orchard.Web/Core/Settings/Metadata/Records/ContentPartFieldDefinitionRecord.cs @@ -0,0 +1,8 @@ +namespace Orchard.Core.Settings.Metadata.Records { + public class ContentPartFieldDefinitionRecord { + public virtual int Id { get; set; } + public virtual ContentFieldDefinitionRecord ContentFieldDefinitionRecord { get; set; } + public virtual string Name { get; set; } + public virtual string Settings { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Settings/Metadata/Records/ContentTypeDefinitionRecord.cs b/src/Orchard.Web/Core/Settings/Metadata/Records/ContentTypeDefinitionRecord.cs new file mode 100644 index 000000000..0f6806c19 --- /dev/null +++ b/src/Orchard.Web/Core/Settings/Metadata/Records/ContentTypeDefinitionRecord.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using Orchard.Data.Conventions; + +namespace Orchard.Core.Settings.Metadata.Records { + public class ContentTypeDefinitionRecord { + public ContentTypeDefinitionRecord() { + ContentTypePartDefinitionRecords = new List(); + } + + public virtual int Id { get; set; } + public virtual string Name { get; set; } + public virtual bool Hidden { get; set; } + public virtual string Settings { get; set; } + + [CascadeAllDeleteOrphan] + public virtual IList ContentTypePartDefinitionRecords { get; set; } + } + +} diff --git a/src/Orchard.Web/Core/Settings/Metadata/Records/ContentTypePartDefinitionRecord.cs b/src/Orchard.Web/Core/Settings/Metadata/Records/ContentTypePartDefinitionRecord.cs new file mode 100644 index 000000000..72a6fe137 --- /dev/null +++ b/src/Orchard.Web/Core/Settings/Metadata/Records/ContentTypePartDefinitionRecord.cs @@ -0,0 +1,7 @@ +namespace Orchard.Core.Settings.Metadata.Records { + public class ContentTypePartDefinitionRecord { + public virtual int Id { get; set; } + public virtual ContentPartDefinitionRecord ContentPartDefinitionRecord { get; set; } + public virtual string Settings { get; set; } + } +} diff --git a/src/Orchard.Web/Modules/Orchard.MetaData/AdminMenu.cs b/src/Orchard.Web/Modules/Orchard.MetaData/AdminMenu.cs index 24956fde2..dbba1d1be 100644 --- a/src/Orchard.Web/Modules/Orchard.MetaData/AdminMenu.cs +++ b/src/Orchard.Web/Modules/Orchard.MetaData/AdminMenu.cs @@ -12,7 +12,7 @@ namespace Orchard.MetaData { { builder.Add(T("Content Types"), "5", menu => menu - .Add(T("Content Types"), "1.0", item => item.Action("ContentTypeList", "MetaData", new { area = "Orchard.MetaData" }).Permission(Permissions.ManageMetaData)) + .Add(T("Content Types"), "1.0", item => item.Action("ContentTypeList", "Admin", new { area = "Orchard.MetaData" }).Permission(Permissions.ManageMetaData)) ); } diff --git a/src/Orchard.Web/Modules/Orchard.MetaData/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.MetaData/Controllers/AdminController.cs new file mode 100644 index 000000000..baae2d64c --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.MetaData/Controllers/AdminController.cs @@ -0,0 +1,82 @@ +using System.Web.Mvc; +using Orchard.ContentManagement.MetaData; +using Orchard.Localization; +using Orchard.MetaData.ViewModels; + +namespace Orchard.MetaData.Controllers { + + public class AdminController : Controller { + private readonly IContentDefinitionManager _contentDefinitionManager; + public IOrchardServices Services { get; set; } + + public AdminController(IOrchardServices services, IContentDefinitionManager contentDefinitionManager) { + _contentDefinitionManager = contentDefinitionManager; + Services = services; + T = NullLocalizer.Instance; + } + + public Localizer T { get; set; } + // + // GET: /ContentTypeList/ + + public ActionResult ContentTypeList(string id) { + + if (!Services.Authorizer.Authorize(Permissions.ManageMetaData, T("Not allowed to manage MetaData"))) + return new HttpUnauthorizedResult(); + + var contentTypes = _contentDefinitionManager.ListTypeDefinitions(); + var contentParts = _contentDefinitionManager.ListPartDefinitions(); + + var model = new ContentTypesIndexViewModel(); + + foreach (var contentType in contentTypes) { + var contentTypeEntry = new ContentTypeEntry { Name = contentType.Name, DisplayName = contentType.Name }; + + if (contentType.Name == id) { + foreach (var contentTypePartNameRecord in contentParts) { + var contentTypePartEntry = new ContentTypePartEntry { Name = contentTypePartNameRecord.Name }; + foreach (var contentTypePartEntryTest in contentType.Parts) { + if (contentTypePartEntryTest.PartDefinition.Name == contentTypePartEntry.Name) { + contentTypePartEntry.Selected = true; + } + } + model.ContentTypeParts.Add(contentTypePartEntry); + } + model.SelectedContentType = contentTypeEntry; + } + model.ContentTypes.Add(contentTypeEntry); + } + return View(model); + } + + + // + // POST: /ContentTypeList/Save + [HttpPost] + public ActionResult Save(string id, FormCollection collection) { + if (!Services.Authorizer.Authorize(Permissions.ManageMetaData, T("Not allowed to manage MetaData"))) + return new HttpUnauthorizedResult(); + + var existingDefinition = _contentDefinitionManager.GetTypeDefinition(id); + + _contentDefinitionManager.AlterTypeDefinition(id, alter => { + foreach(var part in existingDefinition.Parts) { + alter.RemovePart(part.PartDefinition.Name); + } + foreach (var formKey in collection.AllKeys) { + if (formKey.Contains("part_")) { + var partName = formKey.Replace("part_", ""); + alter.WithPart(partName); + } + } + + }); + + return RedirectToAction("ContentTypeList", new { id }); + + + } + + + } +} diff --git a/src/Orchard.Web/Modules/Orchard.MetaData/Controllers/MetaDataController.cs b/src/Orchard.Web/Modules/Orchard.MetaData/Controllers/MetaDataController.cs deleted file mode 100644 index 2e6f991c5..000000000 --- a/src/Orchard.Web/Modules/Orchard.MetaData/Controllers/MetaDataController.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System.Web.Mvc; -using Orchard.ContentManagement.MetaData.Services; -using Orchard.Localization; -using Orchard.MetaData.ViewModels; -using Orchard.UI.Admin; - -namespace Orchard.MetaData.Controllers -{ - [Admin] - public class MetaDataController : Controller - { - private readonly IContentTypeService _contentTypeService; - public IOrchardServices Services { get; set; } - - public MetaDataController(IOrchardServices services, IContentTypeService contentTypeService) - { - _contentTypeService = contentTypeService; - Services = services; - T = NullLocalizer.Instance; - } - - public Localizer T { get; set; } - // - // GET: /ContentTypeList/ - - public ActionResult ContentTypeList(string id) { - - if (!Services.Authorizer.Authorize(Permissions.ManageMetaData, T("Not allowed to manage MetaData"))) - return new HttpUnauthorizedResult(); - - var contentTypes = _contentTypeService.GetContentTypes(); - var contentTypePartNames = _contentTypeService.GetContentTypePartNames(); - - var model = new ContentTypesIndexViewModel(); - - foreach(var contentType in contentTypes) { - var contentTypeEntry = new ContentTypeEntry {Name = contentType.Name,DisplayName = contentType.Name}; - - if (contentType.Name==id) { - foreach(var contentTypePartNameRecord in contentTypePartNames) { - var contentTypePartEntry = new ContentTypePartEntry { Name = contentTypePartNameRecord.PartName }; - foreach(var contentTypePartEntryTest in contentType.ContentParts) { - if (contentTypePartEntryTest.PartName.PartName==contentTypePartEntry.Name) { - contentTypePartEntry.Selected = true; - } - } - model.ContentTypeParts.Add(contentTypePartEntry); - } - model.SelectedContentType = contentTypeEntry; - } - model.ContentTypes.Add(contentTypeEntry); - } - return View(model); - } - - - // - // POST: /ContentTypeList/Save - [HttpPost] - public ActionResult Save(string id, FormCollection collection) - { - if (!Services.Authorizer.Authorize(Permissions.ManageMetaData, T("Not allowed to manage MetaData"))) - return new HttpUnauthorizedResult(); - - var contentTypeRecord = _contentTypeService.GetContentTypeRecord(id); - //using a while loop because we are removing items from the collection - while (contentTypeRecord.ContentParts.Count>0) { - _contentTypeService.UnMapContentTypeToContentPart(contentTypeRecord.Name, contentTypeRecord.ContentParts[0].PartName.PartName); - } - foreach(var formKey in collection.AllKeys) { - if (formKey.Contains("part_")) { - var partName = formKey.Replace("part_", ""); - _contentTypeService.MapContentTypeToContentPart(contentTypeRecord.Name,partName); - } - } - - return RedirectToAction("ContentTypeList", new { id }); - - - } - - - } -} diff --git a/src/Orchard.Web/Modules/Orchard.MetaData/Orchard.MetaData.csproj b/src/Orchard.Web/Modules/Orchard.MetaData/Orchard.MetaData.csproj index 5f6504dcd..5f110a3d1 100644 --- a/src/Orchard.Web/Modules/Orchard.MetaData/Orchard.MetaData.csproj +++ b/src/Orchard.Web/Modules/Orchard.MetaData/Orchard.MetaData.csproj @@ -66,7 +66,7 @@ - + @@ -74,7 +74,7 @@ - + diff --git a/src/Orchard.Web/Modules/Orchard.MetaData/Views/MetaData/ContentTypeList.ascx b/src/Orchard.Web/Modules/Orchard.MetaData/Views/Admin/ContentTypeList.ascx similarity index 100% rename from src/Orchard.Web/Modules/Orchard.MetaData/Views/MetaData/ContentTypeList.ascx rename to src/Orchard.Web/Modules/Orchard.MetaData/Views/Admin/ContentTypeList.ascx diff --git a/src/Orchard.Web/Modules/Orchard.Setup/Services/SetupService.cs b/src/Orchard.Web/Modules/Orchard.Setup/Services/SetupService.cs index 26e50d90a..49cbb27d4 100644 --- a/src/Orchard.Web/Modules/Orchard.Setup/Services/SetupService.cs +++ b/src/Orchard.Web/Modules/Orchard.Setup/Services/SetupService.cs @@ -3,6 +3,8 @@ using System.Linq; using System.Web; using Orchard.Comments.Models; using Orchard.ContentManagement; +using Orchard.ContentManagement.MetaData; +using Orchard.ContentManagement.MetaData.Builders; using Orchard.Core.Common.Models; using Orchard.Core.Navigation.Models; using Orchard.Core.Settings.Models; @@ -79,7 +81,7 @@ namespace Orchard.Setup.Services { } var shellSettings = new ShellSettings(_shellSettings); - + if (string.IsNullOrEmpty(shellSettings.DataProvider)) { shellSettings.DataProvider = context.DatabaseProvider; shellSettings.DataConnectionString = context.DatabaseConnectionString; @@ -169,23 +171,10 @@ namespace Orchard.Setup.Services { authenticationService.SignIn(user, true); } - //Add ContentType mappings - var contentTypeService = environment.Resolve(); - - //Add ContentTypePartNames to MetaData - contentTypeService.AddContentTypePartNameToMetaData("HasComments"); - contentTypeService.AddContentTypePartNameToMetaData("HasTags"); - - //Add mappings from ContentTypes to ContentParts to MetaData - contentTypeService.MapContentTypeToContentPart("blogpost","HasComments"); - contentTypeService.MapContentTypeToContentPart("page", "HasComments"); - contentTypeService.MapContentTypeToContentPart("sandboxpage", "HasComments"); - contentTypeService.MapContentTypeToContentPart("blogpost", "HasTags"); - contentTypeService.MapContentTypeToContentPart("page", "HasTags"); - contentTypeService.MapContentTypeToContentPart("sandboxpage", "HasTags"); - - - + var contentDefinitionManager = environment.Resolve(); + contentDefinitionManager.AlterTypeDefinition("blogpost", cfg => cfg.WithPart("HasComments").WithPart("HasTags")); + contentDefinitionManager.AlterTypeDefinition("page", cfg => cfg.WithPart("HasComments").WithPart("HasTags")); + contentDefinitionManager.AlterTypeDefinition("sandboxpage", cfg => cfg.WithPart("HasComments").WithPart("HasTags")); } catch { environment.Resolve().Cancel(); diff --git a/src/Orchard/ContentManagement/ContentField.cs b/src/Orchard/ContentManagement/ContentField.cs new file mode 100644 index 000000000..953c94953 --- /dev/null +++ b/src/Orchard/ContentManagement/ContentField.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Orchard.ContentManagement.MetaData.Models; + +namespace Orchard.ContentManagement { + public class ContentField { + public string Name { get; set; } + public ContentFieldDefinition Definition { get; set; } + } +} diff --git a/src/Orchard/ContentManagement/ContentItem.cs b/src/Orchard/ContentManagement/ContentItem.cs index 42956b558..a6f751230 100644 --- a/src/Orchard/ContentManagement/ContentItem.cs +++ b/src/Orchard/ContentManagement/ContentItem.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Orchard.ContentManagement.MetaData.Models; using Orchard.ContentManagement.Records; namespace Orchard.ContentManagement { @@ -17,6 +18,7 @@ namespace Orchard.ContentManagement { public int Version { get { return VersionRecord == null ? 0 : VersionRecord.Number; } } public string ContentType { get; set; } + public ContentTypeDefinition TypeDefinition { get; set; } public ContentItemRecord Record { get { return VersionRecord == null ? null : VersionRecord.ContentItemRecord; } } public ContentItemVersionRecord VersionRecord { get; set; } diff --git a/src/Orchard/ContentManagement/ContentPart.cs b/src/Orchard/ContentManagement/ContentPart.cs index 180ea362f..f360ef5bc 100644 --- a/src/Orchard/ContentManagement/ContentPart.cs +++ b/src/Orchard/ContentManagement/ContentPart.cs @@ -1,8 +1,12 @@ +using Orchard.ContentManagement.MetaData.Models; using Orchard.ContentManagement.Utilities; namespace Orchard.ContentManagement { public abstract class ContentPart : IContent { public virtual ContentItem ContentItem { get; set; } + public ContentTypeDefinition TypeDefinition { get; set; } + public ContentTypeDefinition.Part TypePartDefinition { get; set; } + public ContentPartDefinition PartDefinition { get; set; } } public class ContentPart : ContentPart { diff --git a/src/Orchard/ContentManagement/Drivers/ContentItemDriverHandler.cs b/src/Orchard/ContentManagement/Drivers/ContentItemDriverHandler.cs index ca2cbd200..f6d456c32 100644 --- a/src/Orchard/ContentManagement/Drivers/ContentItemDriverHandler.cs +++ b/src/Orchard/ContentManagement/Drivers/ContentItemDriverHandler.cs @@ -5,7 +5,7 @@ using Orchard.Logging; namespace Orchard.ContentManagement.Drivers { [UsedImplicitly] - public class ContentItemDriverHandler : IContentHandler { + public class ContentItemDriverHandler : ContentHandlerBase { private readonly IEnumerable _drivers; public ContentItemDriverHandler(IEnumerable drivers) { @@ -15,33 +15,17 @@ namespace Orchard.ContentManagement.Drivers { public ILogger Logger { get; set; } - IEnumerable IContentHandler.GetContentTypes() { + public override IEnumerable GetContentTypes() { var contentTypes = new List(); _drivers.Invoke(driver=>contentTypes.AddRange(driver.GetContentTypes()), Logger); return contentTypes; } - void IContentHandler.Activating(ActivatingContentContext context) { } - void IContentHandler.Activated(ActivatedContentContext context) { } - void IContentHandler.Creating(CreateContentContext context) { } - void IContentHandler.Created(CreateContentContext context) { } - void IContentHandler.Loading(LoadContentContext context) { } - void IContentHandler.Loaded(LoadContentContext context) { } - void IContentHandler.Versioning(VersionContentContext context) { } - void IContentHandler.Versioned(VersionContentContext context) { } - void IContentHandler.Publishing(PublishContentContext context) { } - void IContentHandler.Published(PublishContentContext context) { } - void IContentHandler.Removing(RemoveContentContext context) { } - void IContentHandler.Removed(RemoveContentContext context) { } - void IContentHandler.Indexing(IndexContentContext context) { } - void IContentHandler.Indexed(IndexContentContext context) { } - - - void IContentHandler.GetContentItemMetadata(GetContentItemMetadataContext context) { + public override void GetContentItemMetadata(GetContentItemMetadataContext context) { _drivers.Invoke(driver => driver.GetContentItemMetadata(context), Logger); } - void IContentHandler.BuildDisplayModel(BuildDisplayModelContext context) { + public override void BuildDisplayModel(BuildDisplayModelContext context) { _drivers.Invoke(driver => { var result = driver.BuildDisplayModel(context); if (result != null) @@ -49,7 +33,7 @@ namespace Orchard.ContentManagement.Drivers { }, Logger); } - void IContentHandler.BuildEditorModel(BuildEditorModelContext context) { + public override void BuildEditorModel(BuildEditorModelContext context) { _drivers.Invoke(driver => { var result = driver.BuildEditorModel(context); if (result != null) @@ -57,7 +41,7 @@ namespace Orchard.ContentManagement.Drivers { }, Logger); } - void IContentHandler.UpdateEditorModel(UpdateEditorModelContext context) { + public override void UpdateEditorModel(UpdateEditorModelContext context) { _drivers.Invoke(driver => { var result = driver.UpdateEditorModel(context); if (result != null) diff --git a/src/Orchard/ContentManagement/Handlers/ContentHandlerBase.cs b/src/Orchard/ContentManagement/Handlers/ContentHandlerBase.cs new file mode 100644 index 000000000..f8026393a --- /dev/null +++ b/src/Orchard/ContentManagement/Handlers/ContentHandlerBase.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Orchard.ContentManagement.Handlers { + public class ContentHandlerBase : IContentHandler { + public virtual IEnumerable GetContentTypes() { + return Enumerable.Empty(); + } + + public virtual void Activating(ActivatingContentContext context) { + } + + public virtual void Activated(ActivatedContentContext context) { + } + + public virtual void Creating(CreateContentContext context) { + } + + public virtual void Created(CreateContentContext context) { + } + + public virtual void Loading(LoadContentContext context) { + } + + public virtual void Loaded(LoadContentContext context) { + } + + public virtual void Versioning(VersionContentContext context) { + } + + public virtual void Versioned(VersionContentContext context) { + } + + public virtual void Publishing(PublishContentContext context) { + } + + public virtual void Published(PublishContentContext context) { + } + + public virtual void Removing(RemoveContentContext context) { + } + + public virtual void Removed(RemoveContentContext context) { + } + + public virtual void Indexing(IndexContentContext context) { + } + + public virtual void Indexed(IndexContentContext context) { + } + + public virtual void GetContentItemMetadata(GetContentItemMetadataContext context) { + } + + public virtual void BuildDisplayModel(BuildDisplayModelContext context) { + } + + public virtual void BuildEditorModel(BuildEditorModelContext context) { + } + + public virtual void UpdateEditorModel(UpdateEditorModelContext context) { + } + } +} \ No newline at end of file diff --git a/src/Orchard/ContentManagement/Handlers/IContentHandler.cs b/src/Orchard/ContentManagement/Handlers/IContentHandler.cs index 846e6a1fd..7dc37cfa7 100644 --- a/src/Orchard/ContentManagement/Handlers/IContentHandler.cs +++ b/src/Orchard/ContentManagement/Handlers/IContentHandler.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Orchard.Events; namespace Orchard.ContentManagement.Handlers { diff --git a/src/Orchard/ContentManagement/MetaData/Builders/ContentPartDefinitionBuilder.cs b/src/Orchard/ContentManagement/MetaData/Builders/ContentPartDefinitionBuilder.cs new file mode 100644 index 000000000..4e9fc0de6 --- /dev/null +++ b/src/Orchard/ContentManagement/MetaData/Builders/ContentPartDefinitionBuilder.cs @@ -0,0 +1,19 @@ +using System; +using Orchard.ContentManagement.MetaData.Models; + +namespace Orchard.ContentManagement.MetaData.Builders { + public class ContentPartDefinitionBuilder { + public ContentPartDefinitionBuilder(ContentPartDefinition partDefinition) { + throw new NotImplementedException(); + } + + public ContentPartDefinition Build() { + throw new NotImplementedException(); + } + + public ContentPartDefinitionBuilder WithSetting(string name, string value) { + throw new NotImplementedException(); + } + + } +} \ No newline at end of file diff --git a/src/Orchard/ContentManagement/MetaData/Builders/ContentTypeDefinitionBuilder.cs b/src/Orchard/ContentManagement/MetaData/Builders/ContentTypeDefinitionBuilder.cs new file mode 100644 index 000000000..b2d997079 --- /dev/null +++ b/src/Orchard/ContentManagement/MetaData/Builders/ContentTypeDefinitionBuilder.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Orchard.ContentManagement.MetaData.Models; + +namespace Orchard.ContentManagement.MetaData.Builders { + public class ContentTypeDefinitionBuilder { + private string _name; + private readonly IList _parts; + private readonly IDictionary _settings; + + public ContentTypeDefinitionBuilder() + : this(new ContentTypeDefinition(null)) { + } + + public ContentTypeDefinitionBuilder(ContentTypeDefinition existing) { + if (existing == null) { + _parts = new List(); + _settings = new Dictionary(); + } + else { + _name = existing.Name; + _parts = existing.Parts.ToList(); + _settings = existing.Settings.ToDictionary(kv => kv.Key, kv => kv.Value); + } + } + + private void Init(ContentTypeDefinition existing) { + + } + + public ContentTypeDefinition Build() { + return new ContentTypeDefinition(_name, _parts, _settings); + } + + public ContentTypeDefinitionBuilder Named(string name) { + _name = name; + return this; + } + + public ContentTypeDefinitionBuilder WithSetting(string name, string value) { + _settings[name] = value; + return this; + } + + public ContentTypeDefinitionBuilder RemovePart(string partName) { + var existingPart = _parts.SingleOrDefault(x => x.PartDefinition.Name == partName); + if (existingPart != null) { + _parts.Remove(existingPart); + } + return this; + } + + public ContentTypeDefinitionBuilder WithPart(string partName) { + return WithPart(partName, configuration => { }); + } + + public ContentTypeDefinitionBuilder WithPart(string partName, Action configuration) { + return WithPart(new ContentPartDefinition(partName), configuration); + } + + public ContentTypeDefinitionBuilder WithPart(ContentPartDefinition partDefinition, Action configuration) { + var existingPart = _parts.SingleOrDefault(x => x.PartDefinition.Name == partDefinition.Name); + if (existingPart != null) { + _parts.Remove(existingPart); + } + else { + existingPart = new ContentTypeDefinition.Part(partDefinition, new Dictionary()); + } + var configurer = new PartConfigurerImpl(existingPart); + configuration(configurer); + _parts.Add(configurer.Build()); + return this; + } + + public abstract class PartConfigurer { + protected readonly IDictionary _settings; + + protected PartConfigurer(ContentTypeDefinition.Part part) { + _settings = part.Settings.ToDictionary(kv => kv.Key, kv => kv.Value); + } + + public PartConfigurer WithSetting(string name, string value) { + _settings[name] = value; + return this; + } + } + + class PartConfigurerImpl : PartConfigurer { + private readonly ContentPartDefinition _partDefinition; + + public PartConfigurerImpl(ContentTypeDefinition.Part part) + : base(part) { + _partDefinition = part.PartDefinition; + } + + public ContentTypeDefinition.Part Build() { + return new ContentTypeDefinition.Part(_partDefinition, _settings); + } + } + + } +} diff --git a/src/Orchard/ContentManagement/MetaData/ContentPartHandler.cs b/src/Orchard/ContentManagement/MetaData/ContentPartHandler.cs index 350e27371..4a4403115 100644 --- a/src/Orchard/ContentManagement/MetaData/ContentPartHandler.cs +++ b/src/Orchard/ContentManagement/MetaData/ContentPartHandler.cs @@ -1,32 +1,27 @@ using System.Collections.Generic; using System.Linq; using Orchard.ContentManagement.Handlers; -using Orchard.ContentManagement.MetaData.Services; using Orchard.ContentManagement.Drivers; namespace Orchard.ContentManagement.MetaData { - public class ContentPartHandler : ContentHandler { + public class ContentPartHandler : ContentHandlerBase { private readonly IEnumerable _contentPartDrivers; - private readonly IContentTypeService _contentTypeService; + private readonly IContentDefinitionManager _contentDefinitionManager; - public ContentPartHandler(IEnumerable contentPartDrivers, IContentTypeService contentTypeService) { + public ContentPartHandler(IEnumerable contentPartDrivers, IContentDefinitionManager contentDefinitionManager) { _contentPartDrivers = contentPartDrivers; - _contentTypeService = contentTypeService; + _contentDefinitionManager = contentDefinitionManager; } - protected override void Activating(ActivatingContentContext context) { - var contentTypeRecord = _contentTypeService.GetContentTypeRecord(context.ContentType); + public override void Activating(ActivatingContentContext context) { + var contentTypeRecord = _contentDefinitionManager.GetTypeDefinition(context.ContentType); if (contentTypeRecord == null) return; - var contentPartInfos = _contentPartDrivers.SelectMany(cpp => cpp.GetPartInfo()).ToList(); - - foreach (var contentTypePartRecord in contentTypeRecord.ContentParts) { - // We might have a part in the database, but the corresponding feature might not - // be enabled anymore, so we need to be resilient to that situation. - var contentPartInfo = contentPartInfos.SingleOrDefault(x => x.PartName == contentTypePartRecord.PartName.PartName); - if (contentPartInfo != null) { - context.Builder.Weld(contentPartInfo.Factory()); + foreach(var partInfo in _contentPartDrivers.SelectMany(cpp => cpp.GetPartInfo())) { + var partName = partInfo.PartName; + if (contentTypeRecord.Parts.Any(p=>p.PartDefinition.Name == partName)) { + context.Builder.Weld(partInfo.Factory()); } } } diff --git a/src/Orchard/ContentManagement/MetaData/IContentDefinitionManager.cs b/src/Orchard/ContentManagement/MetaData/IContentDefinitionManager.cs new file mode 100644 index 000000000..8b635f2a5 --- /dev/null +++ b/src/Orchard/ContentManagement/MetaData/IContentDefinitionManager.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using Orchard.ContentManagement.MetaData.Builders; +using Orchard.ContentManagement.MetaData.Models; + +namespace Orchard.ContentManagement.MetaData { + public interface IContentDefinitionManager : IDependency { + IEnumerable ListTypeDefinitions(); + IEnumerable ListPartDefinitions(); + + ContentTypeDefinition GetTypeDefinition(string name); + ContentPartDefinition GetPartDefinition(string name); + + void StoreTypeDefinition(ContentTypeDefinition contentTypeDefinition); + void StorePartDefinition(ContentPartDefinition contentPartDefinition); + } + + public static class ContentDefinitionManagerExtensions{ + public static void AlterTypeDefinition(this IContentDefinitionManager manager, string name, Action alteration) { + var typeDefinition = manager.GetTypeDefinition(name) ?? new ContentTypeDefinition(name); + var builder = new ContentTypeDefinitionBuilder(typeDefinition); + alteration(builder); + manager.StoreTypeDefinition(builder.Build()); + } + public static void AlterPartDefinition(this IContentDefinitionManager manager, string name, Action alteration) { + var partDefinition = manager.GetPartDefinition(name) ?? new ContentPartDefinition(name); + var builder = new ContentPartDefinitionBuilder(partDefinition); + alteration(builder); + manager.StorePartDefinition(builder.Build()); + } + } +} + diff --git a/src/Orchard/ContentManagement/MetaData/Models/ContentFieldDefinition.cs b/src/Orchard/ContentManagement/MetaData/Models/ContentFieldDefinition.cs new file mode 100644 index 000000000..6b60c4ffd --- /dev/null +++ b/src/Orchard/ContentManagement/MetaData/Models/ContentFieldDefinition.cs @@ -0,0 +1,9 @@ +namespace Orchard.ContentManagement.MetaData.Models { + public class ContentFieldDefinition { + public ContentFieldDefinition(string name) { + Name = name; + } + + public string Name { get; private set; } + } +} diff --git a/src/Orchard/ContentManagement/MetaData/Models/ContentPartDefinition.cs b/src/Orchard/ContentManagement/MetaData/Models/ContentPartDefinition.cs new file mode 100644 index 000000000..dd8bd4e9c --- /dev/null +++ b/src/Orchard/ContentManagement/MetaData/Models/ContentPartDefinition.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Orchard.Utility.Extensions; + +namespace Orchard.ContentManagement.MetaData.Models { + public class ContentPartDefinition { + public ContentPartDefinition(string name, IEnumerable fields, IDictionary settings) { + Name = name; + Fields = fields.ToReadOnlyCollection(); + Settings = settings; + } + + public ContentPartDefinition(string name) { + Name = name; + Fields = Enumerable.Empty(); + Settings = new Dictionary(); + } + + public string Name { get; private set; } + public IEnumerable Fields { get; private set; } + public IDictionary Settings { get; private set; } + + public class Field { + public Field(ContentFieldDefinition contentFieldDefinition, string name, IDictionary settings) { + FieldDefinition = contentFieldDefinition; + Name = name; + Settings = settings; + } + + public string Name { get; private set; } + public ContentFieldDefinition FieldDefinition { get; private set; } + public IDictionary Settings { get; private set; } + } + } +} diff --git a/src/Orchard/ContentManagement/MetaData/Models/ContentTypeDefinition.cs b/src/Orchard/ContentManagement/MetaData/Models/ContentTypeDefinition.cs new file mode 100644 index 000000000..ae9d2a114 --- /dev/null +++ b/src/Orchard/ContentManagement/MetaData/Models/ContentTypeDefinition.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Orchard.ContentManagement.MetaData.Models { + public class ContentTypeDefinition { + public ContentTypeDefinition(string name, IEnumerable parts, IDictionary settings) { + Name = name; + Parts = parts; + Settings = settings; + } + + public ContentTypeDefinition(string name) { + Name = name; + Parts = Enumerable.Empty(); + Settings = new Dictionary(); + } + + public string Name { get; private set; } + public IEnumerable Parts { get; private set; } + public IDictionary Settings { get; private set; } + + public class Part { + public Part(ContentPartDefinition contentPartDefinition, IDictionary settings) { + PartDefinition = contentPartDefinition; + Settings = settings; + } + + public ContentPartDefinition PartDefinition { get; private set; } + public IDictionary Settings { get; private set; } + } + } +} diff --git a/src/Orchard/ContentManagement/MetaData/Records/ContentTypePartNameRecord.cs b/src/Orchard/ContentManagement/MetaData/Records/ContentTypePartNameRecord.cs deleted file mode 100644 index 7f0caddb2..000000000 --- a/src/Orchard/ContentManagement/MetaData/Records/ContentTypePartNameRecord.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Orchard.ContentManagement.MetaData.Records { - public class ContentTypePartNameRecord { - public virtual int Id { get; set; } - public virtual string PartName { get; set; } - } -} diff --git a/src/Orchard/ContentManagement/MetaData/Records/ContentTypePartRecord.cs b/src/Orchard/ContentManagement/MetaData/Records/ContentTypePartRecord.cs deleted file mode 100644 index e723d18e7..000000000 --- a/src/Orchard/ContentManagement/MetaData/Records/ContentTypePartRecord.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Orchard.ContentManagement.MetaData.Records { - public class ContentTypePartRecord { - public virtual int Id { get; set; } - public virtual ContentTypePartNameRecord PartName { get; set; } - } -} diff --git a/src/Orchard/ContentManagement/MetaData/Services/ContentTypeService.cs b/src/Orchard/ContentManagement/MetaData/Services/ContentTypeService.cs deleted file mode 100644 index a0b71bb20..000000000 --- a/src/Orchard/ContentManagement/MetaData/Services/ContentTypeService.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using JetBrains.Annotations; -using Orchard.ContentManagement.MetaData.Records; -using Orchard.ContentManagement.Records; -using Orchard.Data; - -namespace Orchard.ContentManagement.MetaData.Services { - [UsedImplicitly] - public class ContentTypeService : IContentTypeService { - private readonly IRepository _contentTypeRepository; - private readonly IRepository _contentTypePartNameRepository; - private readonly IRepository _contentTypePartRepository; - - public ContentTypeService(IRepository contentTypePartRepository, IRepository contentTypeRepository, IRepository contentTypePartNameRepository) { - _contentTypeRepository = contentTypeRepository; - _contentTypePartNameRepository = contentTypePartNameRepository; - _contentTypePartRepository = contentTypePartRepository; - } - - public ContentTypeRecord GetContentTypeRecord(string contentTypeName) { - return _contentTypeRepository.Fetch(x => x.Name == contentTypeName).SingleOrDefault(); - } - - public ContentTypePartNameRecord GetContentPartNameRecord(string name) { - return _contentTypePartNameRepository.Fetch(x => x.PartName == name).SingleOrDefault(); - } - - public IEnumerable GetContentTypes() { - return _contentTypeRepository.Table.ToList(); - } - - public IEnumerable GetContentTypePartNames() { - return _contentTypePartNameRepository.Table.ToList(); - } - - public void MapContentTypeToContentPart(string contentType, string contentPart) { - // Create content type if needed - var contentTypeRecord = GetContentTypeRecord(contentType); - if (contentTypeRecord == null) { - contentTypeRecord = new ContentTypeRecord { Name = contentType }; - _contentTypeRepository.Create(contentTypeRecord); - } - - // Create part name if needed - var contentTypePartNameRecord = GetContentPartNameRecord(contentPart); - if (contentTypePartNameRecord == null) { - contentTypePartNameRecord = new ContentTypePartNameRecord { PartName = contentPart }; - _contentTypePartNameRepository.Create(contentTypePartNameRecord); - } - - // Add part name to content type - var contentTypePartRecord = new ContentTypePartRecord { PartName = contentTypePartNameRecord }; - contentTypeRecord.ContentParts.Add(contentTypePartRecord); - } - - public void UnMapContentTypeToContentPart(string contentType, string contentPart) { - var contentTypeRecord = GetContentTypeRecord(contentType); - var contentTypePartNameRecord = _contentTypePartNameRepository.Fetch(x => x.PartName == contentPart).Single(); - var contentTypePartRecord = contentTypeRecord.ContentParts.Single(x => x.PartName == contentTypePartNameRecord); - contentTypeRecord.ContentParts.Remove(contentTypePartRecord); - } - - public bool ValidateContentTypeToContentPartMapping(string contentType, string contentPart) { - var contentTypeRecord = GetContentTypeRecord(contentType) ?? new ContentTypeRecord(); - if (contentTypeRecord.ContentParts.Count == 0) - return false; - var contentTypePart = contentTypeRecord.ContentParts.Single(x => x.PartName.PartName == contentPart); - return contentTypePart != null; - } - - - public void AddContentTypePartNameToMetaData(string contentTypePartName) { - var contentTypePartNameRecord = new ContentTypePartNameRecord() { - PartName = contentTypePartName - }; - - _contentTypePartNameRepository.Update(contentTypePartNameRecord); - } - } -} diff --git a/src/Orchard/ContentManagement/MetaData/Services/IContentTypeService.cs b/src/Orchard/ContentManagement/MetaData/Services/IContentTypeService.cs deleted file mode 100644 index 2ab533896..000000000 --- a/src/Orchard/ContentManagement/MetaData/Services/IContentTypeService.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Collections.Generic; -using Orchard.ContentManagement.MetaData.Records; -using Orchard.ContentManagement.Records; - -namespace Orchard.ContentManagement.MetaData.Services -{ - public interface IContentTypeService : IDependency { - void MapContentTypeToContentPart(string contentType, string contentPart); - void UnMapContentTypeToContentPart(string contentType, string contentPart); - void AddContentTypePartNameToMetaData(string contentTypePartName); - ContentTypeRecord GetContentTypeRecord(string contentTypeName); - bool ValidateContentTypeToContentPartMapping(string contentType, string contentPart); - IEnumerable GetContentTypes(); - IEnumerable GetContentTypePartNames(); - ContentTypePartNameRecord GetContentPartNameRecord(string name); - } -} diff --git a/src/Orchard/ContentManagement/MetaData/Services/SettingsFormatter.cs b/src/Orchard/ContentManagement/MetaData/Services/SettingsFormatter.cs new file mode 100644 index 000000000..f7a32f8dc --- /dev/null +++ b/src/Orchard/ContentManagement/MetaData/Services/SettingsFormatter.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using System.Linq; +using System.Xml.Linq; + +namespace Orchard.ContentManagement.MetaData.Services { + public class SettingsFormatter : + IMapper>, + IMapper, XElement> { + + public IDictionary Map(XElement source) { + if (source == null) + return new Dictionary(); + + return source.Attributes().ToDictionary(attr => attr.Name.LocalName, attr => attr.Value); + } + + public XElement Map(IDictionary source) { + if (source == null) + return new XElement("settings"); + + return new XElement("settings", source.Select(kv => new XAttribute(kv.Key, kv.Value))); + } + } +} diff --git a/src/Orchard/ContentManagement/Records/ContentTypeRecord.cs b/src/Orchard/ContentManagement/Records/ContentTypeRecord.cs index b21774f3f..5d05fdc54 100644 --- a/src/Orchard/ContentManagement/Records/ContentTypeRecord.cs +++ b/src/Orchard/ContentManagement/Records/ContentTypeRecord.cs @@ -1,15 +1,7 @@ -using System.Collections.Generic; -using Orchard.ContentManagement.MetaData.Records; -using Orchard.Data.Conventions; - -namespace Orchard.ContentManagement.Records { - public class ContentTypeRecord { - public ContentTypeRecord() { - ContentParts = new List(); - } +namespace Orchard.ContentManagement.Records { + public class ContentTypeRecord { public virtual int Id { get; set; } public virtual string Name { get; set; } - [CascadeAllDeleteOrphan] - public virtual IList ContentParts { get; set; } } + } diff --git a/src/Orchard/Data/SessionLocator.cs b/src/Orchard/Data/SessionLocator.cs index 55085321b..42aebec6a 100644 --- a/src/Orchard/Data/SessionLocator.cs +++ b/src/Orchard/Data/SessionLocator.cs @@ -47,15 +47,15 @@ namespace Orchard.Data { } bool IInterceptor.OnLoad(object entity, object id, object[] state, string[] propertyNames, IType[] types) { - return true; + return false; } bool IInterceptor.OnFlushDirty(object entity, object id, object[] currentState, object[] previousState, string[] propertyNames, IType[] types) { - return true; + return false; } bool IInterceptor.OnSave(object entity, object id, object[] state, string[] propertyNames, IType[] types) { - return true; + return false; } void IInterceptor.OnDelete(object entity, object id, object[] state, string[] propertyNames, IType[] types) { diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index f43d1f4af..80aea76e8 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -119,6 +119,7 @@ 3.5 + False ..\..\lib\yaml\Yaml.dll @@ -129,6 +130,211 @@ + + Code + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + + Code + + + Code + + + + + Code + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + @@ -182,10 +388,6 @@ - - - - @@ -209,18 +411,6 @@ - - - - - - - - - - - - @@ -290,60 +480,8 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -513,9 +651,7 @@ true - - - +