mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Merge
--HG-- branch : dev
This commit is contained in:
@@ -167,7 +167,7 @@ namespace Orchard.Core.Tests.Feeds.Controllers {
|
||||
|
||||
var mockContentManager = new Mock<IContentManager>();
|
||||
mockContentManager.Setup(x => x.GetItemMetadata(It.IsAny<IContent>()))
|
||||
.Returns(new ContentItemMetadata { DisplayText = "foo" });
|
||||
.Returns(new ContentItemMetadata(hello) { DisplayText = "foo" });
|
||||
|
||||
var builder = new ContainerBuilder();
|
||||
//builder.RegisterModule(new ImplicitCollectionSupportModule());
|
||||
|
@@ -3,10 +3,15 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using Autofac;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.FileSystems.AppData;
|
||||
using Orchard.FileSystems.VirtualPath;
|
||||
using Orchard.Indexing;
|
||||
using Orchard.Core.Indexing.Lucene;
|
||||
using Orchard.Services;
|
||||
using Orchard.Tests.Environment.Configuration;
|
||||
using Orchard.Tests.FileSystems.AppData;
|
||||
|
||||
namespace Orchard.Tests.Indexing {
|
||||
public class DefaultIndexProviderTests {
|
||||
@@ -28,8 +33,7 @@ namespace Orchard.Tests.Indexing {
|
||||
}
|
||||
Directory.CreateDirectory(_basePath);
|
||||
|
||||
_appDataFolder = new AppDataFolder();
|
||||
_appDataFolder.SetBasePath(_basePath);
|
||||
_appDataFolder = AppDataFolderTests.CreateAppDataFolder(_basePath);
|
||||
|
||||
var builder = new ContainerBuilder();
|
||||
builder.RegisterType<DefaultIndexProvider>().As<IIndexProvider>();
|
||||
|
@@ -3,10 +3,15 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using Autofac;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.FileSystems.AppData;
|
||||
using Orchard.FileSystems.VirtualPath;
|
||||
using Orchard.Indexing;
|
||||
using Orchard.Core.Indexing.Lucene;
|
||||
using Orchard.Services;
|
||||
using Orchard.Tests.Environment.Configuration;
|
||||
using Orchard.Tests.FileSystems.AppData;
|
||||
|
||||
namespace Orchard.Tests.Indexing {
|
||||
public class DefaultSearchBuilderTests {
|
||||
@@ -28,9 +33,7 @@ namespace Orchard.Tests.Indexing {
|
||||
}
|
||||
Directory.CreateDirectory(_basePath);
|
||||
|
||||
|
||||
_appDataFolder = new AppDataFolder();
|
||||
_appDataFolder.SetBasePath(_basePath);
|
||||
_appDataFolder = AppDataFolderTests.CreateAppDataFolder(_basePath);
|
||||
|
||||
var builder = new ContainerBuilder();
|
||||
builder.RegisterType<DefaultIndexProvider>().As<IIndexProvider>();
|
||||
|
@@ -2,8 +2,8 @@
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.Topology;
|
||||
using Orchard.Environment.Topology.Models;
|
||||
using Orchard.Environment.Descriptor;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.Specs.Hosting.Orchard.Web;
|
||||
using TechTalk.SpecFlow;
|
||||
|
||||
|
@@ -8,16 +8,12 @@ using Autofac.Integration.Web;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Environment.Configuration;
|
||||
|
||||
namespace Orchard.Specs.Hosting.Orchard.Web
|
||||
{
|
||||
public class MvcApplication : HttpApplication
|
||||
{
|
||||
namespace Orchard.Specs.Hosting.Orchard.Web {
|
||||
public class MvcApplication : HttpApplication {
|
||||
private static IContainer _hostContainer;
|
||||
private static IOrchardHost _host;
|
||||
|
||||
|
||||
protected void Application_Start()
|
||||
{
|
||||
protected void Application_Start() {
|
||||
_hostContainer = OrchardStarter.CreateHostContainer(MvcSingletons);
|
||||
_host = _hostContainer.Resolve<IOrchardHost>();
|
||||
Host.Initialize();
|
||||
@@ -27,18 +23,15 @@ namespace Orchard.Specs.Hosting.Orchard.Web
|
||||
|
||||
}
|
||||
|
||||
protected void Application_BeginRequest()
|
||||
{
|
||||
protected void Application_BeginRequest() {
|
||||
Host.BeginRequest();
|
||||
}
|
||||
|
||||
protected void Application_EndRequest()
|
||||
{
|
||||
protected void Application_EndRequest() {
|
||||
Host.EndRequest();
|
||||
}
|
||||
|
||||
protected void MvcSingletons(ContainerBuilder builder)
|
||||
{
|
||||
protected void MvcSingletons(ContainerBuilder builder) {
|
||||
builder.RegisterInstance(ControllerBuilder.Current);
|
||||
builder.RegisterInstance(RouteTable.Routes);
|
||||
builder.RegisterInstance(ModelBinders.Binders);
|
||||
|
@@ -111,7 +111,7 @@
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Roles\Controllers\AdminControllerTests.cs" />
|
||||
<Compile Include="Roles\Services\RoleServiceTests.cs" />
|
||||
<Compile Include="Settings\Topology\ShellDescriptorManagerTests.cs" />
|
||||
<Compile Include="Settings\Blueprint\ShellDescriptorManagerTests.cs" />
|
||||
<Compile Include="Values.cs" />
|
||||
<Compile Include="Users\Controllers\AdminControllerTests.cs" />
|
||||
<Compile Include="Users\Services\MembershipServiceTests.cs" />
|
||||
|
@@ -4,14 +4,14 @@ using System.Linq;
|
||||
using Autofac;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Core.Settings.State;
|
||||
using Orchard.Core.Settings.Topology;
|
||||
using Orchard.Core.Settings.Topology.Records;
|
||||
using Orchard.Core.Settings.Descriptor;
|
||||
using Orchard.Core.Settings.Descriptor.Records;
|
||||
using Orchard.Environment.State;
|
||||
using Orchard.Environment.Topology;
|
||||
using Orchard.Environment.Topology.Models;
|
||||
using Orchard.Environment.Descriptor;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.Events;
|
||||
|
||||
namespace Orchard.Tests.Modules.Settings.Topology {
|
||||
namespace Orchard.Tests.Modules.Settings.Blueprint {
|
||||
[TestFixture]
|
||||
public class ShellDescriptorManagerTests : DatabaseEnabledTestsBase {
|
||||
public override void Register(ContainerBuilder builder) {
|
||||
@@ -45,10 +45,10 @@ namespace Orchard.Tests.Modules.Settings.Topology {
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TopologyShouldBeNullWhenItsNotInitialized() {
|
||||
public void BlueprintShouldBeNullWhenItsNotInitialized() {
|
||||
var manager = _container.Resolve<IShellDescriptorManager>();
|
||||
var topology = manager.GetShellDescriptor();
|
||||
Assert.That(topology, Is.Null);
|
||||
var descriptor = manager.GetShellDescriptor();
|
||||
Assert.That(descriptor, Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -59,9 +59,9 @@ namespace Orchard.Tests.Modules.Settings.Topology {
|
||||
Enumerable.Empty<ShellFeature>(),
|
||||
Enumerable.Empty<ShellParameter>());
|
||||
|
||||
var topology = manager.GetShellDescriptor();
|
||||
Assert.That(topology, Is.Not.Null);
|
||||
Assert.That(topology.SerialNumber, Is.Not.EqualTo(0));
|
||||
var descriptor = manager.GetShellDescriptor();
|
||||
Assert.That(descriptor, Is.Not.Null);
|
||||
Assert.That(descriptor.SerialNumber, Is.Not.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -81,8 +81,8 @@ namespace Orchard.Tests.Modules.Settings.Topology {
|
||||
Enumerable.Empty<ShellFeature>(),
|
||||
Enumerable.Empty<ShellParameter>());
|
||||
|
||||
var topology = manager.GetShellDescriptor();
|
||||
Assert.That(topology.SerialNumber, Is.Not.EqualTo(0));
|
||||
var descriptor = manager.GetShellDescriptor();
|
||||
Assert.That(descriptor.SerialNumber, Is.Not.EqualTo(0));
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => manager.UpdateShellDescriptor(
|
||||
0,
|
||||
@@ -90,18 +90,18 @@ namespace Orchard.Tests.Modules.Settings.Topology {
|
||||
Enumerable.Empty<ShellParameter>()));
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => manager.UpdateShellDescriptor(
|
||||
topology.SerialNumber + 665321,
|
||||
descriptor.SerialNumber + 665321,
|
||||
Enumerable.Empty<ShellFeature>(),
|
||||
Enumerable.Empty<ShellParameter>()));
|
||||
|
||||
manager.UpdateShellDescriptor(
|
||||
topology.SerialNumber,
|
||||
descriptor.SerialNumber,
|
||||
Enumerable.Empty<ShellFeature>(),
|
||||
Enumerable.Empty<ShellParameter>());
|
||||
|
||||
var topology2 = manager.GetShellDescriptor();
|
||||
Assert.That(topology2.SerialNumber, Is.Not.EqualTo(0));
|
||||
Assert.That(topology2.SerialNumber, Is.Not.EqualTo(topology.SerialNumber));
|
||||
var descriptor2 = manager.GetShellDescriptor();
|
||||
Assert.That(descriptor2.SerialNumber, Is.Not.EqualTo(0));
|
||||
Assert.That(descriptor2.SerialNumber, Is.Not.EqualTo(descriptor.SerialNumber));
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => manager.UpdateShellDescriptor(
|
||||
0,
|
||||
@@ -109,17 +109,17 @@ namespace Orchard.Tests.Modules.Settings.Topology {
|
||||
Enumerable.Empty<ShellParameter>()));
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => manager.UpdateShellDescriptor(
|
||||
topology.SerialNumber,
|
||||
descriptor.SerialNumber,
|
||||
Enumerable.Empty<ShellFeature>(),
|
||||
Enumerable.Empty<ShellParameter>()));
|
||||
|
||||
manager.UpdateShellDescriptor(
|
||||
topology2.SerialNumber,
|
||||
descriptor2.SerialNumber,
|
||||
Enumerable.Empty<ShellFeature>(),
|
||||
Enumerable.Empty<ShellParameter>());
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => manager.UpdateShellDescriptor(
|
||||
topology2.SerialNumber,
|
||||
descriptor2.SerialNumber,
|
||||
Enumerable.Empty<ShellFeature>(),
|
||||
Enumerable.Empty<ShellParameter>()));
|
||||
}
|
@@ -2,8 +2,9 @@
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Data.Builders;
|
||||
using Orchard.Environment.Topology;
|
||||
using Orchard.Environment.Topology.Models;
|
||||
using Orchard.Environment.Descriptor;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.Environment.ShellBuilders.Models;
|
||||
using Orchard.Tests.Records;
|
||||
|
||||
namespace Orchard.Tests.Data.Builders {
|
||||
@@ -49,7 +50,7 @@ namespace Orchard.Tests.Data.Builders {
|
||||
[Test]
|
||||
public void SQLiteSchemaShouldBeGeneratedAndUsable() {
|
||||
var recordDescriptors = new[] {
|
||||
new RecordTopology {TableName = "Hello", Type = typeof (FooRecord)}
|
||||
new RecordBlueprint {TableName = "Hello", Type = typeof (FooRecord)}
|
||||
};
|
||||
var manager = (ISessionFactoryBuilder)new SessionFactoryBuilder();
|
||||
var sessionFactory = manager.BuildSessionFactory(new SessionFactoryParameters {
|
||||
@@ -78,7 +79,7 @@ namespace Orchard.Tests.Data.Builders {
|
||||
CreateSqlServerDatabase(databasePath);
|
||||
|
||||
var recordDescriptors = new[] {
|
||||
new RecordTopology {TableName = "Hello", Type = typeof (FooRecord)}
|
||||
new RecordBlueprint {TableName = "Hello", Type = typeof (FooRecord)}
|
||||
};
|
||||
|
||||
var manager = (ISessionFactoryBuilder)new SessionFactoryBuilder();
|
||||
|
@@ -9,7 +9,8 @@ using NHibernate;
|
||||
using NHibernate.Tool.hbm2ddl;
|
||||
using Orchard.Data;
|
||||
using Orchard.Data.Builders;
|
||||
using Orchard.Environment.Topology.Models;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.Environment.ShellBuilders.Models;
|
||||
|
||||
namespace Orchard.Tests {
|
||||
public static class DataUtility {
|
||||
@@ -18,7 +19,7 @@ namespace Orchard.Tests {
|
||||
//var persistenceModel = AutoMap.Source(new Types(types))
|
||||
// .Alterations(alt => AddAlterations(alt, types))
|
||||
// .Conventions.AddFromAssemblyOf<DataModule>();
|
||||
var persistenceModel = AbstractBuilder.CreatePersistenceModel(types.Select(t => new RecordTopology { TableName = "Test_" + t.Name,Type = t }));
|
||||
var persistenceModel = AbstractBuilder.CreatePersistenceModel(types.Select(t => new RecordBlueprint { TableName = "Test_" + t.Name,Type = t }));
|
||||
|
||||
return Fluently.Configure()
|
||||
.Database(SQLiteConfiguration.Standard.UsingFile(fileName).ShowSql())
|
||||
|
@@ -3,11 +3,15 @@ using System.Runtime.Serialization;
|
||||
using System.Xml;
|
||||
using Autofac;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Environment.Topology;
|
||||
using Orchard.Environment.Topology.Models;
|
||||
using Orchard.Environment.Descriptor;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.FileSystems.AppData;
|
||||
using Orchard.FileSystems.VirtualPath;
|
||||
using Orchard.Services;
|
||||
using Orchard.Tests.Environment.Configuration;
|
||||
using Orchard.Tests.FileSystems.AppData;
|
||||
|
||||
namespace Orchard.Tests.Environment.Topology {
|
||||
namespace Orchard.Tests.Environment.Blueprint {
|
||||
[TestFixture]
|
||||
public class DefaultShellDescriptorCacheTests {
|
||||
private IContainer _container;
|
||||
@@ -19,8 +23,9 @@ namespace Orchard.Tests.Environment.Topology {
|
||||
_tempFolder = Path.GetTempFileName();
|
||||
File.Delete(_tempFolder);
|
||||
Directory.CreateDirectory(_tempFolder);
|
||||
_appDataFolder = new AppDataFolder();
|
||||
_appDataFolder.SetBasePath(_tempFolder);
|
||||
|
||||
_appDataFolder = AppDataFolderTests.CreateAppDataFolder(_tempFolder);
|
||||
|
||||
var builder = new ContainerBuilder();
|
||||
builder.RegisterInstance(_appDataFolder).As<IAppDataFolder>();
|
||||
builder.RegisterType<ShellDescriptorCache>().As<IShellDescriptorCache>();
|
@@ -2,21 +2,25 @@
|
||||
using System.Linq;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.FileSystems.AppData;
|
||||
using Orchard.FileSystems.VirtualPath;
|
||||
using Orchard.Services;
|
||||
using Orchard.Tests.FileSystems.AppData;
|
||||
|
||||
namespace Orchard.Tests.Environment.Configuration {
|
||||
[TestFixture]
|
||||
public class DefaultTenantManagerTests {
|
||||
private string _tempFolder;
|
||||
private AppDataFolder _appData;
|
||||
private IAppDataFolder _appData;
|
||||
|
||||
[SetUp]
|
||||
public void Init() {
|
||||
_appData = new AppDataFolder();
|
||||
_tempFolder = Path.GetTempFileName();
|
||||
File.Delete(_tempFolder);
|
||||
_appData.SetBasePath(_tempFolder);
|
||||
|
||||
_appData = AppDataFolderTests.CreateAppDataFolder(_tempFolder);
|
||||
}
|
||||
[TearDown]
|
||||
public void Term() {
|
||||
|
@@ -11,7 +11,8 @@ using Orchard.ContentManagement.Records;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.Environment.Topology;
|
||||
using Orchard.Environment.Descriptor;
|
||||
using Orchard.Environment.ShellBuilders;
|
||||
using Orchard.Tests.Environment.Utility;
|
||||
using Orchard.Tests.Records;
|
||||
using Orchard.Tests.Utility;
|
||||
@@ -57,19 +58,19 @@ namespace Orchard.Tests.Environment {
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TopologyIsNotNull() {
|
||||
var descriptor = Build.TopologyDescriptor();
|
||||
public void BlueprintIsNotNull() {
|
||||
var descriptor = Build.ShellDescriptor();
|
||||
|
||||
var compositionStrategy = _container.Resolve<ICompositionStrategy>();
|
||||
var topology = compositionStrategy.Compose(BuildDefaultSettings(), descriptor);
|
||||
var blueprint = compositionStrategy.Compose(BuildDefaultSettings(), descriptor);
|
||||
|
||||
Assert.That(topology, Is.Not.Null);
|
||||
Assert.That(blueprint, Is.Not.Null);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void DependenciesFromFeatureArePutIntoTopology() {
|
||||
var descriptor = Build.TopologyDescriptor().WithFeatures("Foo", "Bar");
|
||||
public void DependenciesFromFeatureArePutIntoBlueprint() {
|
||||
var descriptor = Build.ShellDescriptor().WithFeatures("Foo", "Bar");
|
||||
|
||||
_extensionDescriptors = new[] {
|
||||
Build.ExtensionDescriptor("Foo").WithFeatures("Foo"),
|
||||
@@ -80,16 +81,16 @@ namespace Orchard.Tests.Environment {
|
||||
_featureTypes["Bar"] = new[] { typeof(BarService1) };
|
||||
|
||||
var compositionStrategy = _container.Resolve<ICompositionStrategy>();
|
||||
var topology = compositionStrategy.Compose(BuildDefaultSettings(), descriptor);
|
||||
var blueprint = compositionStrategy.Compose(BuildDefaultSettings(), descriptor);
|
||||
|
||||
Assert.That(topology, Is.Not.Null);
|
||||
Assert.That(topology.Dependencies.Count(), Is.EqualTo(2));
|
||||
Assert.That(blueprint, Is.Not.Null);
|
||||
Assert.That(blueprint.Dependencies.Count(), Is.EqualTo(2));
|
||||
|
||||
var foo = topology.Dependencies.SingleOrDefault(t => t.Type == typeof(FooService1));
|
||||
var foo = blueprint.Dependencies.SingleOrDefault(t => t.Type == typeof(FooService1));
|
||||
Assert.That(foo, Is.Not.Null);
|
||||
Assert.That(foo.Feature.Descriptor.Name, Is.EqualTo("Foo"));
|
||||
|
||||
var bar = topology.Dependencies.SingleOrDefault(t => t.Type == typeof(BarService1));
|
||||
var bar = blueprint.Dependencies.SingleOrDefault(t => t.Type == typeof(BarService1));
|
||||
Assert.That(bar, Is.Not.Null);
|
||||
Assert.That(bar.Feature.Descriptor.Name, Is.EqualTo("Bar"));
|
||||
}
|
||||
@@ -109,7 +110,7 @@ namespace Orchard.Tests.Environment {
|
||||
|
||||
[Test]
|
||||
public void DependenciesAreGivenParameters() {
|
||||
var descriptor = Build.TopologyDescriptor()
|
||||
var descriptor = Build.ShellDescriptor()
|
||||
.WithFeatures("Foo")
|
||||
.WithParameter<FooService1>("one", "two")
|
||||
.WithParameter<FooService1>("three", "four");
|
||||
@@ -121,9 +122,9 @@ namespace Orchard.Tests.Environment {
|
||||
_featureTypes["Foo"] = new[] { typeof(FooService1) };
|
||||
|
||||
var compositionStrategy = _container.Resolve<ICompositionStrategy>();
|
||||
var topology = compositionStrategy.Compose(BuildDefaultSettings(), descriptor);
|
||||
var blueprint = compositionStrategy.Compose(BuildDefaultSettings(), descriptor);
|
||||
|
||||
var foo = topology.Dependencies.SingleOrDefault(t => t.Type == typeof(FooService1));
|
||||
var foo = blueprint.Dependencies.SingleOrDefault(t => t.Type == typeof(FooService1));
|
||||
Assert.That(foo, Is.Not.Null);
|
||||
Assert.That(foo.Parameters.Count(), Is.EqualTo(2));
|
||||
Assert.That(foo.Parameters.Single(x => x.Name == "one").Value, Is.EqualTo("two"));
|
||||
@@ -131,8 +132,8 @@ namespace Orchard.Tests.Environment {
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ModulesArePutIntoTopology() {
|
||||
var descriptor = Build.TopologyDescriptor().WithFeatures("Foo", "Bar");
|
||||
public void ModulesArePutIntoBlueprint() {
|
||||
var descriptor = Build.ShellDescriptor().WithFeatures("Foo", "Bar");
|
||||
|
||||
_extensionDescriptors = new[] {
|
||||
Build.ExtensionDescriptor("Foo").WithFeatures("Foo"),
|
||||
@@ -143,10 +144,10 @@ namespace Orchard.Tests.Environment {
|
||||
_featureTypes["Bar"] = new[] { typeof(BetaModule) };
|
||||
|
||||
var compositionStrategy = _container.Resolve<ICompositionStrategy>();
|
||||
var topology = compositionStrategy.Compose(BuildDefaultSettings(), descriptor);
|
||||
var blueprint = compositionStrategy.Compose(BuildDefaultSettings(), descriptor);
|
||||
|
||||
var alpha = topology.Dependencies.Single(x => x.Type == typeof(AlphaModule));
|
||||
var beta = topology.Dependencies.Single(x => x.Type == typeof(BetaModule));
|
||||
var alpha = blueprint.Dependencies.Single(x => x.Type == typeof(AlphaModule));
|
||||
var beta = blueprint.Dependencies.Single(x => x.Type == typeof(BetaModule));
|
||||
|
||||
Assert.That(alpha.Feature.Descriptor.Name, Is.EqualTo("Foo"));
|
||||
Assert.That(beta.Feature.Descriptor.Name, Is.EqualTo("Bar"));
|
||||
@@ -162,8 +163,8 @@ namespace Orchard.Tests.Environment {
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ControllersArePutIntoTopologyWithAreaAndControllerName() {
|
||||
var descriptor = Build.TopologyDescriptor().WithFeatures("Foo Plus", "Bar Minus");
|
||||
public void ControllersArePutIntoBlueprintWithAreaAndControllerName() {
|
||||
var descriptor = Build.ShellDescriptor().WithFeatures("Foo Plus", "Bar Minus");
|
||||
|
||||
_extensionDescriptors = new[] {
|
||||
Build.ExtensionDescriptor("MyCompany.Foo", "Foo").WithFeatures("Foo", "Foo Plus"),
|
||||
@@ -176,11 +177,11 @@ namespace Orchard.Tests.Environment {
|
||||
_featureTypes["Bar Minus"] = new[] { typeof(DeltaController), typeof(EpsilonController) };
|
||||
|
||||
var compositionStrategy = _container.Resolve<ICompositionStrategy>();
|
||||
var topology = compositionStrategy.Compose(BuildDefaultSettings(), descriptor);
|
||||
var blueprint = compositionStrategy.Compose(BuildDefaultSettings(), descriptor);
|
||||
|
||||
var gamma = topology.Controllers.Single(x => x.Type == typeof(GammaController));
|
||||
var delta = topology.Controllers.Single(x => x.Type == typeof(DeltaController));
|
||||
var epsilon = topology.Controllers.Single(x => x.Type == typeof(EpsilonController));
|
||||
var gamma = blueprint.Controllers.Single(x => x.Type == typeof(GammaController));
|
||||
var delta = blueprint.Controllers.Single(x => x.Type == typeof(DeltaController));
|
||||
var epsilon = blueprint.Controllers.Single(x => x.Type == typeof(EpsilonController));
|
||||
|
||||
Assert.That(gamma.Feature.Descriptor.Name, Is.EqualTo("Foo Plus"));
|
||||
Assert.That(gamma.AreaName, Is.EqualTo("MyCompany.Foo"));
|
||||
@@ -213,8 +214,8 @@ namespace Orchard.Tests.Environment {
|
||||
|
||||
|
||||
[Test]
|
||||
public void RecordsArePutIntoTopologyWithTableName() {
|
||||
var descriptor = Build.TopologyDescriptor().WithFeatures("Foo Plus", "Bar", "Bar Minus");
|
||||
public void RecordsArePutIntoBlueprintWithTableName() {
|
||||
var descriptor = Build.ShellDescriptor().WithFeatures("Foo Plus", "Bar", "Bar Minus");
|
||||
|
||||
_extensionDescriptors = new[] {
|
||||
Build.ExtensionDescriptor("MyCompany.Foo", "Foo").WithFeatures("Foo", "Foo Plus"),
|
||||
@@ -227,10 +228,10 @@ namespace Orchard.Tests.Environment {
|
||||
_featureTypes["Bar Minus"] = Enumerable.Empty<Type>();
|
||||
|
||||
var compositionStrategy = _container.Resolve<ICompositionStrategy>();
|
||||
var topology = compositionStrategy.Compose(BuildDefaultSettings(), descriptor);
|
||||
var blueprint = compositionStrategy.Compose(BuildDefaultSettings(), descriptor);
|
||||
|
||||
var foo = topology.Records.Single(x => x.Type == typeof(FooRecord));
|
||||
var bar = topology.Records.Single(x => x.Type == typeof(BarRecord));
|
||||
var foo = blueprint.Records.Single(x => x.Type == typeof(FooRecord));
|
||||
var bar = blueprint.Records.Single(x => x.Type == typeof(BarRecord));
|
||||
|
||||
Assert.That(foo.Feature.Descriptor.Name, Is.EqualTo("Foo Plus"));
|
||||
Assert.That(foo.TableName, Is.EqualTo("MyCompany_Foo_FooRecord"));
|
||||
@@ -241,14 +242,14 @@ namespace Orchard.Tests.Environment {
|
||||
|
||||
[Test]
|
||||
public void CoreRecordsAreAddedAutomatically() {
|
||||
var descriptor = Build.TopologyDescriptor().WithFeatures("Orchard.Framework");
|
||||
var descriptor = Build.ShellDescriptor().WithFeatures("Orchard.Framework");
|
||||
|
||||
var compositionStrategy = _container.Resolve<ICompositionStrategy>();
|
||||
var topology = compositionStrategy.Compose(BuildDefaultSettings(), descriptor);
|
||||
var blueprint = compositionStrategy.Compose(BuildDefaultSettings(), descriptor);
|
||||
|
||||
var ct = topology.Records.Single(x => x.Type == typeof(ContentTypeRecord));
|
||||
var ci = topology.Records.Single(x => x.Type == typeof(ContentItemRecord));
|
||||
var civ = topology.Records.Single(x => x.Type == typeof(ContentItemVersionRecord));
|
||||
var ct = blueprint.Records.Single(x => x.Type == typeof(ContentTypeRecord));
|
||||
var ci = blueprint.Records.Single(x => x.Type == typeof(ContentItemRecord));
|
||||
var civ = blueprint.Records.Single(x => x.Type == typeof(ContentItemVersionRecord));
|
||||
|
||||
Assert.That(ct.Feature.Descriptor.Name, Is.EqualTo("Orchard.Framework"));
|
||||
Assert.That(ct.TableName, Is.EqualTo("Orchard_Framework_ContentTypeRecord"));
|
||||
@@ -264,7 +265,7 @@ namespace Orchard.Tests.Environment {
|
||||
public void DataPrefixChangesTableName() {
|
||||
var settings = BuildDefaultSettings();
|
||||
settings.DataTablePrefix = "Yadda";
|
||||
var descriptor = Build.TopologyDescriptor().WithFeatures("Foo Plus", "Bar", "Bar Minus");
|
||||
var descriptor = Build.ShellDescriptor().WithFeatures("Foo Plus", "Bar", "Bar Minus");
|
||||
|
||||
_extensionDescriptors = new[] {
|
||||
Build.ExtensionDescriptor("MyCompany.Foo", "Foo").WithFeatures("Foo", "Foo Plus"),
|
||||
@@ -277,10 +278,10 @@ namespace Orchard.Tests.Environment {
|
||||
_featureTypes["Bar Minus"] = Enumerable.Empty<Type>();
|
||||
|
||||
var compositionStrategy = _container.Resolve<ICompositionStrategy>();
|
||||
var topology = compositionStrategy.Compose(settings, descriptor);
|
||||
var blueprint = compositionStrategy.Compose(settings, descriptor);
|
||||
|
||||
var foo = topology.Records.Single(x => x.Type == typeof(FooRecord));
|
||||
var bar = topology.Records.Single(x => x.Type == typeof(BarRecord));
|
||||
var foo = blueprint.Records.Single(x => x.Type == typeof(FooRecord));
|
||||
var bar = blueprint.Records.Single(x => x.Type == typeof(BarRecord));
|
||||
|
||||
Assert.That(foo.Feature.Descriptor.Name, Is.EqualTo("Foo Plus"));
|
||||
Assert.That(foo.TableName, Is.EqualTo("Yadda_MyCompany_Foo_FooRecord"));
|
||||
|
@@ -9,6 +9,7 @@ using Autofac;
|
||||
using Autofac.Integration.Web;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Caching;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Environment.AutofacUtil;
|
||||
using Orchard.Environment.Configuration;
|
||||
@@ -16,13 +17,15 @@ using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.Extensions.Folders;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.Environment.ShellBuilders;
|
||||
using Orchard.Environment.Topology;
|
||||
using Orchard.Environment.Topology.Models;
|
||||
using Orchard.Environment.Descriptor;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.FileSystems.AppData;
|
||||
using Orchard.Mvc;
|
||||
using Orchard.Mvc.ModelBinders;
|
||||
using Orchard.Mvc.Routes;
|
||||
using Orchard.Tests.Environment.Configuration;
|
||||
using Orchard.Tests.Environment.TestDependencies;
|
||||
using Orchard.Tests.FileSystems.AppData;
|
||||
using Orchard.Tests.Stubs;
|
||||
using Orchard.Tests.Utility;
|
||||
|
||||
@@ -38,6 +41,12 @@ namespace Orchard.Tests.Environment {
|
||||
|
||||
[SetUp]
|
||||
public void Init() {
|
||||
var temp = Path.GetTempFileName();
|
||||
File.Delete(temp);
|
||||
Directory.CreateDirectory(temp);
|
||||
|
||||
var appDataFolder = AppDataFolderTests.CreateAppDataFolder(temp);
|
||||
|
||||
_controllerBuilder = new ControllerBuilder();
|
||||
_routeCollection = new RouteCollection();
|
||||
_modelBinderDictionary = new ModelBinderDictionary();
|
||||
@@ -51,6 +60,7 @@ namespace Orchard.Tests.Environment {
|
||||
builder.RegisterType<ModelBinderPublisher>().As<IModelBinderPublisher>();
|
||||
builder.RegisterType<ShellContextFactory>().As<IShellContextFactory>();
|
||||
builder.RegisterType<StubExtensionManager>().As<IExtensionManager>();
|
||||
builder.RegisterInstance(appDataFolder);
|
||||
builder.RegisterInstance(_controllerBuilder);
|
||||
builder.RegisterInstance(_routeCollection);
|
||||
builder.RegisterInstance(_modelBinderDictionary);
|
||||
@@ -75,13 +85,6 @@ namespace Orchard.Tests.Environment {
|
||||
_container.Mock<IOrchardShellEvents>()
|
||||
.Setup(e=>e.Activated());
|
||||
|
||||
var temp = Path.GetTempFileName();
|
||||
File.Delete(temp);
|
||||
Directory.CreateDirectory(temp);
|
||||
|
||||
_container.Resolve<IAppDataFolder>()
|
||||
.SetBasePath(temp);
|
||||
|
||||
var updater = new ContainerUpdater();
|
||||
updater.RegisterInstance(_container).SingleInstance();
|
||||
updater.Update(_lifetime);
|
||||
@@ -94,15 +97,6 @@ namespace Orchard.Tests.Environment {
|
||||
yield return ext;
|
||||
}
|
||||
|
||||
public IEnumerable<ExtensionEntry> ActiveExtensions_Obsolete() {
|
||||
var feature = FrameworkFeature(new FeatureDescriptor { Name = "Orchard.Framework" });
|
||||
yield return new ExtensionEntry {
|
||||
Assembly = feature.ExportedTypes.First().Assembly,
|
||||
Descriptor = AvailableExtensions().First(),
|
||||
ExportedTypes = feature.ExportedTypes
|
||||
};
|
||||
}
|
||||
|
||||
public IEnumerable<Feature> LoadFeatures(IEnumerable<FeatureDescriptor> featureDescriptors) {
|
||||
foreach (var descriptor in featureDescriptors) {
|
||||
if (descriptor.Name == "Orchard.Framework") {
|
||||
@@ -129,6 +123,10 @@ namespace Orchard.Tests.Environment {
|
||||
public void UninstallExtension(string extensionType, string extensionName) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Monitor(Action<IVolatileToken> monitor) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public class StubShellSettingsLoader : IShellSettingsManager {
|
||||
|
@@ -0,0 +1,361 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Autofac;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.Extensions.Folders;
|
||||
using Orchard.Environment.Extensions.Loaders;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.Tests.Extensions.ExtensionTypes;
|
||||
|
||||
namespace Orchard.Tests.Environment.Extensions {
|
||||
[TestFixture]
|
||||
public class ExtensionLoaderCoordinatorTests {
|
||||
private IContainer _container;
|
||||
private IExtensionManager _manager;
|
||||
private IExtensionLoaderCoordinator _loader;
|
||||
private StubFolders _folders;
|
||||
|
||||
[SetUp]
|
||||
public void Init() {
|
||||
var builder = new ContainerBuilder();
|
||||
_folders = new StubFolders();
|
||||
builder.RegisterInstance(_folders).As<IExtensionFolders>();
|
||||
builder.RegisterType<ExtensionManager>().As<IExtensionManager>();
|
||||
_container = builder.Build();
|
||||
_manager = _container.Resolve<IExtensionManager>();
|
||||
}
|
||||
|
||||
public class StubFolders : IExtensionFolders {
|
||||
public StubFolders() {
|
||||
Manifests = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
public IDictionary<string, string> Manifests { get; set; }
|
||||
|
||||
public IEnumerable<ExtensionDescriptor> AvailableExtensions() {
|
||||
foreach (var e in Manifests) {
|
||||
string name = e.Key;
|
||||
var parseResult = ExtensionFolders.ParseManifest(Manifests[name]);
|
||||
yield return ExtensionFolders.GetDescriptorForExtension("~/", name, "Module", parseResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class StubLoaders : ExtensionLoaderBase {
|
||||
#region Implementation of IExtensionLoader
|
||||
|
||||
public override int Order {
|
||||
get { return 1; }
|
||||
}
|
||||
|
||||
public override ExtensionProbeEntry Probe(ExtensionDescriptor descriptor) {
|
||||
return new ExtensionProbeEntry { Descriptor = descriptor, Loader = this };
|
||||
}
|
||||
|
||||
public override ExtensionEntry Load(ExtensionDescriptor descriptor) {
|
||||
return new ExtensionEntry { Descriptor = descriptor, ExportedTypes = new[] { typeof(Alpha), typeof(Beta), typeof(Phi) } };
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void AvailableExtensionsShouldFollowCatalogLocations() {
|
||||
_folders.Manifests.Add("foo", "name: Foo");
|
||||
_folders.Manifests.Add("bar", "name: Bar");
|
||||
_folders.Manifests.Add("frap", "name: Frap");
|
||||
_folders.Manifests.Add("quad", "name: Quad");
|
||||
|
||||
var available = _manager.AvailableExtensions();
|
||||
|
||||
Assert.That(available.Count(), Is.EqualTo(4));
|
||||
Assert.That(available, Has.Some.Property("Name").EqualTo("foo"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionDescriptorsShouldHaveNameAndVersion() {
|
||||
|
||||
_folders.Manifests.Add("Sample", @"
|
||||
name: Sample Extension
|
||||
version: 2.x
|
||||
");
|
||||
|
||||
var descriptor = _manager.AvailableExtensions().Single();
|
||||
Assert.That(descriptor.Name, Is.EqualTo("Sample"));
|
||||
Assert.That(descriptor.DisplayName, Is.EqualTo("Sample Extension"));
|
||||
Assert.That(descriptor.Version, Is.EqualTo("2.x"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionDescriptorsShouldBeParsedForMinimalModuleTxt() {
|
||||
|
||||
_folders.Manifests.Add("SuperWiki", @"
|
||||
name: SuperWiki
|
||||
version: 1.0.3
|
||||
orchardversion: 1
|
||||
features:
|
||||
SuperWiki:
|
||||
Description: My super wiki module for Orchard.
|
||||
");
|
||||
|
||||
var descriptor = _manager.AvailableExtensions().Single();
|
||||
Assert.That(descriptor.Name, Is.EqualTo("SuperWiki"));
|
||||
Assert.That(descriptor.Version, Is.EqualTo("1.0.3"));
|
||||
Assert.That(descriptor.OrchardVersion, Is.EqualTo("1"));
|
||||
Assert.That(descriptor.Features.Count(), Is.EqualTo(1));
|
||||
Assert.That(descriptor.Features.First().Name, Is.EqualTo("SuperWiki"));
|
||||
Assert.That(descriptor.Features.First().Extension.Name, Is.EqualTo("SuperWiki"));
|
||||
Assert.That(descriptor.Features.First().Description, Is.EqualTo("My super wiki module for Orchard."));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionDescriptorsShouldBeParsedForCompleteModuleTxt() {
|
||||
|
||||
_folders.Manifests.Add("MyCompany.AnotherWiki", @"
|
||||
name: AnotherWiki
|
||||
author: Coder Notaprogrammer
|
||||
website: http://anotherwiki.codeplex.com
|
||||
version: 1.2.3
|
||||
orchardversion: 1
|
||||
features:
|
||||
AnotherWiki:
|
||||
Description: My super wiki module for Orchard.
|
||||
Dependencies: Versioning, Search
|
||||
Category: Content types
|
||||
AnotherWiki Editor:
|
||||
Description: A rich editor for wiki contents.
|
||||
Dependencies: TinyMCE, AnotherWiki
|
||||
Category: Input methods
|
||||
AnotherWiki DistributionList:
|
||||
Description: Sends e-mail alerts when wiki contents gets published.
|
||||
Dependencies: AnotherWiki, Email Subscriptions
|
||||
Category: Email
|
||||
AnotherWiki Captcha:
|
||||
Description: Kills spam. Or makes it zombie-like.
|
||||
Dependencies: AnotherWiki, reCaptcha
|
||||
Category: Spam
|
||||
");
|
||||
|
||||
var descriptor = _manager.AvailableExtensions().Single();
|
||||
Assert.That(descriptor.Name, Is.EqualTo("MyCompany.AnotherWiki"));
|
||||
Assert.That(descriptor.DisplayName, Is.EqualTo("AnotherWiki"));
|
||||
Assert.That(descriptor.Author, Is.EqualTo("Coder Notaprogrammer"));
|
||||
Assert.That(descriptor.WebSite, Is.EqualTo("http://anotherwiki.codeplex.com"));
|
||||
Assert.That(descriptor.Version, Is.EqualTo("1.2.3"));
|
||||
Assert.That(descriptor.OrchardVersion, Is.EqualTo("1"));
|
||||
Assert.That(descriptor.Features.Count(), Is.EqualTo(5));
|
||||
foreach (var featureDescriptor in descriptor.Features) {
|
||||
switch (featureDescriptor.Name) {
|
||||
case "AnotherWiki":
|
||||
Assert.That(featureDescriptor.Extension, Is.SameAs(descriptor));
|
||||
Assert.That(featureDescriptor.Description, Is.EqualTo("My super wiki module for Orchard."));
|
||||
Assert.That(featureDescriptor.Category, Is.EqualTo("Content types"));
|
||||
Assert.That(featureDescriptor.Dependencies.Count(), Is.EqualTo(2));
|
||||
Assert.That(featureDescriptor.Dependencies.Contains("Versioning"));
|
||||
Assert.That(featureDescriptor.Dependencies.Contains("Search"));
|
||||
break;
|
||||
case "AnotherWiki Editor":
|
||||
Assert.That(featureDescriptor.Extension, Is.SameAs(descriptor));
|
||||
Assert.That(featureDescriptor.Description, Is.EqualTo("A rich editor for wiki contents."));
|
||||
Assert.That(featureDescriptor.Category, Is.EqualTo("Input methods"));
|
||||
Assert.That(featureDescriptor.Dependencies.Count(), Is.EqualTo(2));
|
||||
Assert.That(featureDescriptor.Dependencies.Contains("TinyMCE"));
|
||||
Assert.That(featureDescriptor.Dependencies.Contains("AnotherWiki"));
|
||||
break;
|
||||
case "AnotherWiki DistributionList":
|
||||
Assert.That(featureDescriptor.Extension, Is.SameAs(descriptor));
|
||||
Assert.That(featureDescriptor.Description, Is.EqualTo("Sends e-mail alerts when wiki contents gets published."));
|
||||
Assert.That(featureDescriptor.Category, Is.EqualTo("Email"));
|
||||
Assert.That(featureDescriptor.Dependencies.Count(), Is.EqualTo(2));
|
||||
Assert.That(featureDescriptor.Dependencies.Contains("AnotherWiki"));
|
||||
Assert.That(featureDescriptor.Dependencies.Contains("Email Subscriptions"));
|
||||
break;
|
||||
case "AnotherWiki Captcha":
|
||||
Assert.That(featureDescriptor.Extension, Is.SameAs(descriptor));
|
||||
Assert.That(featureDescriptor.Description, Is.EqualTo("Kills spam. Or makes it zombie-like."));
|
||||
Assert.That(featureDescriptor.Category, Is.EqualTo("Spam"));
|
||||
Assert.That(featureDescriptor.Dependencies.Count(), Is.EqualTo(2));
|
||||
Assert.That(featureDescriptor.Dependencies.Contains("AnotherWiki"));
|
||||
Assert.That(featureDescriptor.Dependencies.Contains("reCaptcha"));
|
||||
break;
|
||||
// default feature.
|
||||
case "MyCompany.AnotherWiki":
|
||||
Assert.That(featureDescriptor.Extension, Is.SameAs(descriptor));
|
||||
break;
|
||||
default:
|
||||
Assert.Fail("Features not parsed correctly");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionManagerShouldLoadFeatures() {
|
||||
var extensionLoader = new StubLoaders();
|
||||
var extensionFolder = new StubFolders();
|
||||
|
||||
extensionFolder.Manifests.Add("TestModule", @"
|
||||
name: TestModule
|
||||
version: 1.0.3
|
||||
orchardversion: 1
|
||||
features:
|
||||
TestModule:
|
||||
Description: My test module for Orchard.
|
||||
TestFeature:
|
||||
Description: Contains the Phi type.
|
||||
");
|
||||
|
||||
IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader });
|
||||
var testFeature = extensionManager.AvailableExtensions()
|
||||
.SelectMany(x => x.Features);
|
||||
|
||||
var features = extensionManager.LoadFeatures(testFeature);
|
||||
var types = features.SelectMany(x => x.ExportedTypes);
|
||||
|
||||
Assert.That(types.Count(), Is.Not.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionManagerFeaturesContainNonAbstractClasses() {
|
||||
var extensionLoader = new StubLoaders();
|
||||
var extensionFolder = new StubFolders();
|
||||
|
||||
extensionFolder.Manifests.Add("TestModule", @"
|
||||
name: TestModule
|
||||
version: 1.0.3
|
||||
orchardversion: 1
|
||||
features:
|
||||
TestModule:
|
||||
Description: My test module for Orchard.
|
||||
TestFeature:
|
||||
Description: Contains the Phi type.
|
||||
");
|
||||
|
||||
IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader });
|
||||
var testFeature = extensionManager.AvailableExtensions()
|
||||
.SelectMany(x => x.Features);
|
||||
|
||||
var features = extensionManager.LoadFeatures(testFeature);
|
||||
var types = features.SelectMany(x => x.ExportedTypes);
|
||||
|
||||
foreach (var type in types) {
|
||||
Assert.That(type.IsClass);
|
||||
Assert.That(!type.IsAbstract);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionManagerShouldThrowIfFeatureDoesNotExist() {
|
||||
var featureDescriptor = new FeatureDescriptor { Name = "NoSuchFeature" };
|
||||
Assert.Throws<ArgumentException>(() => _manager.LoadFeatures(new[] { featureDescriptor }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionManagerTestFeatureAttribute() {
|
||||
var extensionLoader = new StubLoaders();
|
||||
var extensionFolder = new StubFolders();
|
||||
|
||||
extensionFolder.Manifests.Add("TestModule", @"
|
||||
name: TestModule
|
||||
version: 1.0.3
|
||||
orchardversion: 1
|
||||
features:
|
||||
TestModule:
|
||||
Description: My test module for Orchard.
|
||||
TestFeature:
|
||||
Description: Contains the Phi type.
|
||||
");
|
||||
|
||||
IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader });
|
||||
var testFeature = extensionManager.AvailableExtensions()
|
||||
.SelectMany(x => x.Features)
|
||||
.Single(x => x.Name == "TestFeature");
|
||||
|
||||
foreach (var feature in extensionManager.LoadFeatures(new[] { testFeature })) {
|
||||
foreach (var type in feature.ExportedTypes) {
|
||||
foreach (OrchardFeatureAttribute featureAttribute in type.GetCustomAttributes(typeof(OrchardFeatureAttribute), false)) {
|
||||
Assert.That(featureAttribute.FeatureName, Is.EqualTo("TestFeature"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionManagerLoadFeatureReturnsTypesFromSpecificFeaturesWithFeatureAttribute() {
|
||||
var extensionLoader = new StubLoaders();
|
||||
var extensionFolder = new StubFolders();
|
||||
|
||||
extensionFolder.Manifests.Add("TestModule", @"
|
||||
name: TestModule
|
||||
version: 1.0.3
|
||||
orchardversion: 1
|
||||
features:
|
||||
TestModule:
|
||||
Description: My test module for Orchard.
|
||||
TestFeature:
|
||||
Description: Contains the Phi type.
|
||||
");
|
||||
|
||||
IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader });
|
||||
var testFeature = extensionManager.AvailableExtensions()
|
||||
.SelectMany(x => x.Features)
|
||||
.Single(x => x.Name == "TestFeature");
|
||||
|
||||
foreach (var feature in extensionManager.LoadFeatures(new[] { testFeature })) {
|
||||
foreach (var type in feature.ExportedTypes) {
|
||||
Assert.That(type == typeof(Phi));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionManagerLoadFeatureDoesNotReturnTypesFromNonMatchingFeatures() {
|
||||
var extensionLoader = new StubLoaders();
|
||||
var extensionFolder = new StubFolders();
|
||||
|
||||
extensionFolder.Manifests.Add("TestModule", @"
|
||||
name: TestModule
|
||||
version: 1.0.3
|
||||
orchardversion: 1
|
||||
features:
|
||||
TestModule:
|
||||
Description: My test module for Orchard.
|
||||
TestFeature:
|
||||
Description: Contains the Phi type.
|
||||
");
|
||||
|
||||
IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader });
|
||||
var testModule = extensionManager.AvailableExtensions()
|
||||
.SelectMany(x => x.Features)
|
||||
.Single(x => x.Name == "TestModule");
|
||||
|
||||
foreach (var feature in extensionManager.LoadFeatures(new[] { testModule })) {
|
||||
foreach (var type in feature.ExportedTypes) {
|
||||
Assert.That(type != typeof(Phi));
|
||||
Assert.That((type == typeof(Alpha) || (type == typeof(Beta))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ModuleNameIsIntroducedAsFeatureImplicitly() {
|
||||
var extensionLoader = new StubLoaders();
|
||||
var extensionFolder = new StubFolders();
|
||||
|
||||
extensionFolder.Manifests.Add("Minimalistic", @"
|
||||
name: Minimalistic
|
||||
version: 1.0.3
|
||||
orchardversion: 1
|
||||
");
|
||||
|
||||
IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader });
|
||||
var minimalisticModule = extensionManager.AvailableExtensions().Single(x => x.Name == "Minimalistic");
|
||||
|
||||
Assert.That(minimalisticModule.Features.Count(), Is.EqualTo(1));
|
||||
Assert.That(minimalisticModule.Features.Single().Name, Is.EqualTo("Minimalistic"));
|
||||
}
|
||||
}
|
||||
}
|
@@ -8,7 +8,6 @@ using Orchard.Environment.Extensions.Folders;
|
||||
using Orchard.Environment.Extensions.Loaders;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.Tests.Extensions.ExtensionTypes;
|
||||
using Yaml.Grammar;
|
||||
|
||||
namespace Orchard.Tests.Environment.Extensions {
|
||||
[TestFixture]
|
||||
@@ -35,7 +34,7 @@ namespace Orchard.Tests.Environment.Extensions {
|
||||
public IDictionary<string, string> Manifests { get; set; }
|
||||
|
||||
public IEnumerable<ExtensionDescriptor> AvailableExtensions() {
|
||||
foreach(var e in Manifests) {
|
||||
foreach (var e in Manifests) {
|
||||
string name = e.Key;
|
||||
var parseResult = ExtensionFolders.ParseManifest(Manifests[name]);
|
||||
yield return ExtensionFolders.GetDescriptorForExtension("~/", name, "Module", parseResult);
|
||||
@@ -43,14 +42,18 @@ namespace Orchard.Tests.Environment.Extensions {
|
||||
}
|
||||
}
|
||||
|
||||
public class StubLoaders : IExtensionLoader {
|
||||
public class StubLoaders : ExtensionLoaderBase {
|
||||
#region Implementation of IExtensionLoader
|
||||
|
||||
public int Order {
|
||||
public override int Order {
|
||||
get { return 1; }
|
||||
}
|
||||
|
||||
public ExtensionEntry Load(ExtensionDescriptor descriptor) {
|
||||
public override ExtensionProbeEntry Probe(ExtensionDescriptor descriptor) {
|
||||
return new ExtensionProbeEntry { Descriptor = descriptor, Loader = this };
|
||||
}
|
||||
|
||||
public override ExtensionEntry Load(ExtensionDescriptor descriptor) {
|
||||
return new ExtensionEntry { Descriptor = descriptor, ExportedTypes = new[] { typeof(Alpha), typeof(Beta), typeof(Phi) } };
|
||||
}
|
||||
|
||||
@@ -246,27 +249,35 @@ features:
|
||||
[Test]
|
||||
public void ExtensionManagerShouldThrowIfFeatureDoesNotExist() {
|
||||
var featureDescriptor = new FeatureDescriptor { Name = "NoSuchFeature" };
|
||||
Assert.Throws<ArgumentException>(() => _manager.LoadFeatures(new [] { featureDescriptor }));
|
||||
Assert.Throws<ArgumentException>(() => _manager.LoadFeatures(new[] { featureDescriptor }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionManagerTestFeatureAttribute() {
|
||||
var extensionManager = new Moq.Mock<IExtensionManager>();
|
||||
var extensionEntry = new ExtensionEntry {
|
||||
Descriptor = new ExtensionDescriptor { Name = "Module"},
|
||||
ExportedTypes = new[] { typeof(Alpha), typeof(Beta), typeof(Phi) }
|
||||
};
|
||||
extensionEntry.Descriptor.Features = new[] {
|
||||
new FeatureDescriptor
|
||||
{Name = "Module", Extension = extensionEntry.Descriptor},
|
||||
new FeatureDescriptor
|
||||
{Name = "TestFeature", Extension = extensionEntry.Descriptor}
|
||||
};
|
||||
extensionManager.Setup(x => x.ActiveExtensions_Obsolete()).Returns(new[] {extensionEntry});
|
||||
var extensionLoader = new StubLoaders();
|
||||
var extensionFolder = new StubFolders();
|
||||
|
||||
foreach (var type in extensionManager.Object.ActiveExtensions_Obsolete().SelectMany(x => x.ExportedTypes)) {
|
||||
foreach (OrchardFeatureAttribute featureAttribute in type.GetCustomAttributes(typeof(OrchardFeatureAttribute), false)) {
|
||||
Assert.That(featureAttribute.FeatureName, Is.EqualTo("TestFeature"));
|
||||
extensionFolder.Manifests.Add("TestModule", @"
|
||||
name: TestModule
|
||||
version: 1.0.3
|
||||
orchardversion: 1
|
||||
features:
|
||||
TestModule:
|
||||
Description: My test module for Orchard.
|
||||
TestFeature:
|
||||
Description: Contains the Phi type.
|
||||
");
|
||||
|
||||
IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader });
|
||||
var testFeature = extensionManager.AvailableExtensions()
|
||||
.SelectMany(x => x.Features)
|
||||
.Single(x => x.Name == "TestFeature");
|
||||
|
||||
foreach (var feature in extensionManager.LoadFeatures(new[] { testFeature })) {
|
||||
foreach (var type in feature.ExportedTypes) {
|
||||
foreach (OrchardFeatureAttribute featureAttribute in type.GetCustomAttributes(typeof(OrchardFeatureAttribute), false)) {
|
||||
Assert.That(featureAttribute.FeatureName, Is.EqualTo("TestFeature"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -320,7 +331,7 @@ features:
|
||||
.SelectMany(x => x.Features)
|
||||
.Single(x => x.Name == "TestModule");
|
||||
|
||||
foreach (var feature in extensionManager.LoadFeatures(new [] { testModule })) {
|
||||
foreach (var feature in extensionManager.LoadFeatures(new[] { testModule })) {
|
||||
foreach (var type in feature.ExportedTypes) {
|
||||
Assert.That(type != typeof(Phi));
|
||||
Assert.That((type == typeof(Alpha) || (type == typeof(Beta))));
|
||||
|
@@ -14,7 +14,8 @@ using Orchard.Environment.AutofacUtil.DynamicProxy2;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.Environment.ShellBuilders;
|
||||
using Orchard.Environment.Topology.Models;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.Environment.ShellBuilders.Models;
|
||||
|
||||
namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
[TestFixture]
|
||||
@@ -33,32 +34,32 @@ namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
ShellSettings CreateSettings() {
|
||||
return new ShellSettings {Name = "Default"};
|
||||
}
|
||||
ShellTopology CreateTopology(params ShellTopologyItem[] items) {
|
||||
return new ShellTopology {
|
||||
Dependencies = items.OfType<DependencyTopology>(),
|
||||
Controllers = items.OfType<ControllerTopology>(),
|
||||
Records = items.OfType<RecordTopology>(),
|
||||
ShellBlueprint CreateBlueprint(params ShellBlueprintItem[] items) {
|
||||
return new ShellBlueprint {
|
||||
Dependencies = items.OfType<DependencyBlueprint>(),
|
||||
Controllers = items.OfType<ControllerBlueprint>(),
|
||||
Records = items.OfType<RecordBlueprint>(),
|
||||
};
|
||||
}
|
||||
|
||||
DependencyTopology WithModule<T>() {
|
||||
return new DependencyTopology { Type = typeof(T), Parameters = Enumerable.Empty<ShellParameter>() };
|
||||
DependencyBlueprint WithModule<T>() {
|
||||
return new DependencyBlueprint { Type = typeof(T), Parameters = Enumerable.Empty<ShellParameter>() };
|
||||
}
|
||||
|
||||
ControllerTopology WithController<T>(string areaName, string controllerName) {
|
||||
return new ControllerTopology { Type = typeof(T), AreaName = areaName, ControllerName = controllerName };
|
||||
ControllerBlueprint WithController<T>(string areaName, string controllerName) {
|
||||
return new ControllerBlueprint { Type = typeof(T), AreaName = areaName, ControllerName = controllerName };
|
||||
}
|
||||
|
||||
DependencyTopology WithDependency<T>() {
|
||||
return new DependencyTopology { Type = typeof(T), Parameters = Enumerable.Empty<ShellParameter>() };
|
||||
DependencyBlueprint WithDependency<T>() {
|
||||
return new DependencyBlueprint { Type = typeof(T), Parameters = Enumerable.Empty<ShellParameter>() };
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ShouldReturnChildLifetimeScopeNamedShell() {
|
||||
var settings = CreateSettings();
|
||||
var topology = CreateTopology();
|
||||
var blueprint = CreateBlueprint();
|
||||
var factory = _container.Resolve<IShellContainerFactory>();
|
||||
var shellContainer = factory.CreateContainer(settings, topology);
|
||||
var shellContainer = factory.CreateContainer(settings, blueprint);
|
||||
|
||||
Assert.That(shellContainer.Tag, Is.EqualTo("shell"));
|
||||
|
||||
@@ -72,12 +73,12 @@ namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
[Test]
|
||||
public void ControllersAreRegisteredAsKeyedServices() {
|
||||
var settings = CreateSettings();
|
||||
var topology = CreateTopology(
|
||||
var blueprint = CreateBlueprint(
|
||||
WithModule<TestModule>(),
|
||||
WithController<TestController>("foo", "bar"));
|
||||
|
||||
var factory = _container.Resolve<IShellContainerFactory>();
|
||||
var shellContainer = factory.CreateContainer(settings, topology);
|
||||
var shellContainer = factory.CreateContainer(settings, blueprint);
|
||||
var controllers = shellContainer.Resolve<IIndex<string, IController>>();
|
||||
var controller = controllers["foo/bar"];
|
||||
Assert.That(controller, Is.Not.Null);
|
||||
@@ -91,12 +92,12 @@ namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
[Test]
|
||||
public void ModulesAreResolvedAndRegistered() {
|
||||
var settings = CreateSettings();
|
||||
var topology = CreateTopology(
|
||||
var blueprint = CreateBlueprint(
|
||||
WithModule<TestModule>(),
|
||||
WithController<TestController>("foo", "bar"));
|
||||
|
||||
var factory = _container.Resolve<IShellContainerFactory>();
|
||||
var shellContainer = factory.CreateContainer(settings, topology);
|
||||
var shellContainer = factory.CreateContainer(settings, blueprint);
|
||||
|
||||
var controllerMetas = shellContainer.Resolve<IIndex<string, Meta<IController>>>();
|
||||
var metadata = controllerMetas["foo/bar"].Metadata;
|
||||
@@ -114,11 +115,11 @@ namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
[Test]
|
||||
public void ModulesMayResolveHostServices() {
|
||||
var settings = CreateSettings();
|
||||
var topology = CreateTopology(
|
||||
var blueprint = CreateBlueprint(
|
||||
WithModule<ModuleUsingThatComponent>());
|
||||
|
||||
var factory = _container.Resolve<IShellContainerFactory>();
|
||||
var shellContainer = factory.CreateContainer(settings, topology);
|
||||
var shellContainer = factory.CreateContainer(settings, blueprint);
|
||||
Assert.That(shellContainer.Resolve<string>(), Is.EqualTo("Module was loaded"));
|
||||
}
|
||||
|
||||
@@ -141,11 +142,11 @@ namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
[Test]
|
||||
public void DependenciesAreResolvable() {
|
||||
var settings = CreateSettings();
|
||||
var topology = CreateTopology(
|
||||
var blueprint = CreateBlueprint(
|
||||
WithDependency<TestDependency>());
|
||||
|
||||
var factory = _container.Resolve<IShellContainerFactory>();
|
||||
var shellContainer = factory.CreateContainer(settings, topology);
|
||||
var shellContainer = factory.CreateContainer(settings, blueprint);
|
||||
|
||||
var testDependency = shellContainer.Resolve<ITestDependency>();
|
||||
Assert.That(testDependency, Is.Not.Null);
|
||||
@@ -161,14 +162,14 @@ namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
[Test]
|
||||
public void ExtraInformationCanDropIntoProperties() {
|
||||
var settings = CreateSettings();
|
||||
var topology = CreateTopology(
|
||||
var blueprint = CreateBlueprint(
|
||||
WithDependency<TestDependency2>());
|
||||
|
||||
topology.Dependencies.Single().Feature =
|
||||
blueprint.Dependencies.Single().Feature =
|
||||
new Feature { Descriptor = new FeatureDescriptor { Name = "Hello" } };
|
||||
|
||||
var factory = _container.Resolve<IShellContainerFactory>();
|
||||
var shellContainer = factory.CreateContainer(settings, topology);
|
||||
var shellContainer = factory.CreateContainer(settings, blueprint);
|
||||
|
||||
var testDependency = shellContainer.Resolve<ITestDependency>();
|
||||
Assert.That(testDependency, Is.Not.Null);
|
||||
@@ -187,10 +188,10 @@ namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
[Test]
|
||||
public void ParametersMayOrMayNotBeUsedAsPropertiesAndConstructorParameters() {
|
||||
var settings = CreateSettings();
|
||||
var topology = CreateTopology(
|
||||
var blueprint = CreateBlueprint(
|
||||
WithDependency<TestDependency3>());
|
||||
|
||||
topology.Dependencies.Single().Parameters =
|
||||
blueprint.Dependencies.Single().Parameters =
|
||||
new[] {
|
||||
new ShellParameter {Name = "alpha", Value = "-a-"},
|
||||
new ShellParameter {Name = "Beta", Value = "-b-"},
|
||||
@@ -198,7 +199,7 @@ namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
};
|
||||
|
||||
var factory = _container.Resolve<IShellContainerFactory>();
|
||||
var shellContainer = factory.CreateContainer(settings, topology);
|
||||
var shellContainer = factory.CreateContainer(settings, blueprint);
|
||||
|
||||
var testDependency = shellContainer.Resolve<ITestDependency>();
|
||||
Assert.That(testDependency, Is.Not.Null);
|
||||
@@ -231,20 +232,20 @@ namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
[Test]
|
||||
public void DynamicProxyIsInEffect() {
|
||||
var settings = CreateSettings();
|
||||
var topology = CreateTopology(
|
||||
var blueprint = CreateBlueprint(
|
||||
WithModule<ProxModule>(),
|
||||
WithDependency<ProxDependency>());
|
||||
|
||||
var factory = _container.Resolve<IShellContainerFactory>();
|
||||
var shellContainer = factory.CreateContainer(settings, topology);
|
||||
var shellContainer = factory.CreateContainer(settings, blueprint);
|
||||
|
||||
var testDependency = shellContainer.Resolve<IProxDependency>();
|
||||
Assert.That(testDependency.Hello(), Is.EqualTo("Foo"));
|
||||
|
||||
var topology2 = CreateTopology(
|
||||
var blueprint2 = CreateBlueprint(
|
||||
WithDependency<ProxDependency>());
|
||||
|
||||
var shellContainer2 = factory.CreateContainer(settings, topology2);
|
||||
var shellContainer2 = factory.CreateContainer(settings, blueprint2);
|
||||
|
||||
var testDependency2 = shellContainer2.Resolve<IProxDependency>();
|
||||
Assert.That(testDependency2.Hello(), Is.EqualTo("World"));
|
||||
@@ -281,10 +282,10 @@ namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
[Test]
|
||||
public void DynamicProxyAndShellSettingsAreResolvableToSameInstances() {
|
||||
var settings = CreateSettings();
|
||||
var topology = CreateTopology();
|
||||
var blueprint = CreateBlueprint();
|
||||
|
||||
var factory = _container.Resolve<IShellContainerFactory>();
|
||||
var shellContainer = factory.CreateContainer(settings, topology);
|
||||
var shellContainer = factory.CreateContainer(settings, blueprint);
|
||||
|
||||
var proxa = shellContainer.Resolve<DynamicProxyContext>();
|
||||
var proxb = shellContainer.Resolve<DynamicProxyContext>();
|
||||
@@ -297,8 +298,8 @@ namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
Assert.That(setta, Is.SameAs(settb));
|
||||
|
||||
var settings2 = CreateSettings();
|
||||
var topology2 = CreateTopology();
|
||||
var shellContainer2 = factory.CreateContainer(settings2, topology2);
|
||||
var blueprint2 = CreateBlueprint();
|
||||
var shellContainer2 = factory.CreateContainer(settings2, blueprint2);
|
||||
|
||||
var proxa2 = shellContainer2.Resolve<DynamicProxyContext>();
|
||||
var proxb2 = shellContainer2.Resolve<DynamicProxyContext>();
|
||||
|
@@ -5,8 +5,9 @@ using NUnit.Framework;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.ShellBuilders;
|
||||
using Orchard.Environment.Topology;
|
||||
using Orchard.Environment.Topology.Models;
|
||||
using Orchard.Environment.Descriptor;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.Environment.ShellBuilders.Models;
|
||||
using Orchard.Tests.Utility;
|
||||
|
||||
namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
@@ -25,33 +26,33 @@ namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
[Test]
|
||||
public void NormalExecutionReturnsExpectedObjects() {
|
||||
var settings = new ShellSettings { Name = "Default" };
|
||||
var topologyDescriptor = new ShellDescriptor { SerialNumber = 6655321 };
|
||||
var topology = new ShellTopology();
|
||||
var descriptor = new ShellDescriptor { SerialNumber = 6655321 };
|
||||
var blueprint = new ShellBlueprint();
|
||||
var shellLifetimeScope = _container.BeginLifetimeScope("shell");
|
||||
|
||||
_container.Mock<IShellDescriptorCache>()
|
||||
.Setup(x => x.Fetch("Default"))
|
||||
.Returns(topologyDescriptor);
|
||||
.Returns(descriptor);
|
||||
|
||||
_container.Mock<ICompositionStrategy>()
|
||||
.Setup(x => x.Compose(settings, topologyDescriptor))
|
||||
.Returns(topology);
|
||||
.Setup(x => x.Compose(settings, descriptor))
|
||||
.Returns(blueprint);
|
||||
|
||||
_container.Mock<IShellContainerFactory>()
|
||||
.Setup(x => x.CreateContainer(settings, topology))
|
||||
.Setup(x => x.CreateContainer(settings, blueprint))
|
||||
.Returns(shellLifetimeScope);
|
||||
|
||||
_container.Mock<IShellDescriptorManager>()
|
||||
.Setup(x => x.GetShellDescriptor())
|
||||
.Returns(topologyDescriptor);
|
||||
.Returns(descriptor);
|
||||
|
||||
var factory = _container.Resolve<IShellContextFactory>();
|
||||
|
||||
var context = factory.CreateShellContext(settings);
|
||||
|
||||
Assert.That(context.Settings, Is.SameAs(settings));
|
||||
Assert.That(context.Descriptor, Is.SameAs(topologyDescriptor));
|
||||
Assert.That(context.Topology, Is.SameAs(topology));
|
||||
Assert.That(context.Descriptor, Is.SameAs(descriptor));
|
||||
Assert.That(context.Blueprint, Is.SameAs(blueprint));
|
||||
Assert.That(context.LifetimeScope, Is.SameAs(shellLifetimeScope));
|
||||
Assert.That(context.Shell, Is.SameAs(shellLifetimeScope.Resolve<IOrchardShell>()));
|
||||
}
|
||||
@@ -60,7 +61,7 @@ namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
public void CreatingSetupContextUsesOrchardSetupFeature() {
|
||||
var settings = default(ShellSettings);
|
||||
var descriptor = default(ShellDescriptor);
|
||||
var topology = new ShellTopology();
|
||||
var blueprint = new ShellBlueprint();
|
||||
|
||||
_container.Mock<ICompositionStrategy>()
|
||||
.Setup(x => x.Compose(It.IsAny<ShellSettings>(), It.IsAny<ShellDescriptor>()))
|
||||
@@ -68,10 +69,10 @@ namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
settings = s;
|
||||
descriptor = d;
|
||||
})
|
||||
.Returns(topology);
|
||||
.Returns(blueprint);
|
||||
|
||||
_container.Mock<IShellContainerFactory>()
|
||||
.Setup(x => x.CreateContainer(It.IsAny<ShellSettings>(), topology))
|
||||
.Setup(x => x.CreateContainer(It.IsAny<ShellSettings>(), blueprint))
|
||||
.Returns(_container.BeginLifetimeScope("shell"));
|
||||
|
||||
var factory = _container.Resolve<IShellContextFactory>();
|
||||
|
@@ -5,7 +5,7 @@ using NUnit.Framework;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.ShellBuilders;
|
||||
using Orchard.Environment.State;
|
||||
using Orchard.Environment.Topology.Models;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.Events;
|
||||
using Orchard.Tests.Utility;
|
||||
|
||||
|
@@ -1,11 +1,11 @@
|
||||
using System.Linq;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.Environment.Topology.Models;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
|
||||
namespace Orchard.Tests.Environment.Utility {
|
||||
static class Build {
|
||||
|
||||
public static ShellDescriptor TopologyDescriptor() {
|
||||
public static ShellDescriptor ShellDescriptor() {
|
||||
var descriptor = new ShellDescriptor {
|
||||
Features = Enumerable.Empty<ShellFeature>(),
|
||||
Parameters = Enumerable.Empty<ShellParameter>(),
|
||||
|
@@ -2,13 +2,25 @@
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Orchard.FileSystems.AppData;
|
||||
using Orchard.Tests.Stubs;
|
||||
|
||||
namespace Orchard.Tests.Environment.Configuration {
|
||||
namespace Orchard.Tests.FileSystems.AppData {
|
||||
[TestFixture]
|
||||
public class AppDataFolderTests {
|
||||
private string _tempFolder;
|
||||
private IAppDataFolder _appDataFolder;
|
||||
|
||||
public class StubAppDataFolderRoot : IAppDataFolderRoot {
|
||||
public string RootPath { get; set; }
|
||||
public string RootFolder { get; set; }
|
||||
}
|
||||
|
||||
public static IAppDataFolder CreateAppDataFolder(string tempFolder) {
|
||||
var folderRoot = new StubAppDataFolderRoot {RootPath = "~/App_Data", RootFolder = tempFolder};
|
||||
var monitor = new StubVirtualPathMonitor();
|
||||
return new AppDataFolder(folderRoot, monitor);
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void Init() {
|
||||
_tempFolder = Path.GetTempFileName();
|
||||
@@ -18,8 +30,7 @@ namespace Orchard.Tests.Environment.Configuration {
|
||||
File.WriteAllText(Path.Combine(_tempFolder, "alpha\\gamma.txt"), "gamma-content");
|
||||
Directory.CreateDirectory(Path.Combine(_tempFolder, "alpha\\omega"));
|
||||
|
||||
_appDataFolder = new AppDataFolder();
|
||||
_appDataFolder.SetBasePath(_tempFolder);
|
||||
_appDataFolder = CreateAppDataFolder(_tempFolder);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
@@ -31,8 +42,8 @@ namespace Orchard.Tests.Environment.Configuration {
|
||||
public void ListFilesShouldContainSubPathAndFileName() {
|
||||
var files = _appDataFolder.ListFiles("alpha");
|
||||
Assert.That(files.Count(), Is.EqualTo(2));
|
||||
Assert.That(files, Has.Some.EqualTo("alpha\\beta.txt"));
|
||||
Assert.That(files, Has.Some.EqualTo("alpha\\gamma.txt"));
|
||||
Assert.That(files, Has.Some.EqualTo("alpha/beta.txt"));
|
||||
Assert.That(files, Has.Some.EqualTo("alpha/gamma.txt"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -51,7 +62,7 @@ namespace Orchard.Tests.Environment.Configuration {
|
||||
public void ListSubdirectoriesShouldContainFullSubpath() {
|
||||
var files = _appDataFolder.ListDirectories("alpha");
|
||||
Assert.That(files.Count(), Is.EqualTo(1));
|
||||
Assert.That(files, Has.Some.EqualTo("alpha\\omega"));
|
||||
Assert.That(files, Has.Some.EqualTo("alpha/omega"));
|
||||
}
|
||||
|
||||
[Test]
|
@@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Orchard.FileSystems.Dependencies;
|
||||
using Orchard.Tests.Stubs;
|
||||
|
||||
namespace Orchard.Tests.FileSystems.Dependencies {
|
||||
[TestFixture]
|
||||
public class DependenciesFolderTests {
|
||||
[Test]
|
||||
public void LoadDescriptorsShouldReturnEmptyList() {
|
||||
var clock = new StubClock();
|
||||
var appDataFolder = new StubAppDataFolder(clock);
|
||||
var dependenciesFolder = new DefaultDependenciesFolder(new StubCacheManager(), appDataFolder);
|
||||
|
||||
var e = dependenciesFolder.LoadDescriptors();
|
||||
Assert.That(e, Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void StoreDescriptorsShouldWork() {
|
||||
var clock = new StubClock();
|
||||
var appDataFolder = new StubAppDataFolder(clock);
|
||||
var dependenciesFolder = new DefaultDependenciesFolder(new StubCacheManager(), appDataFolder);
|
||||
|
||||
var d = new DependencyDescriptor {
|
||||
Name = "name",
|
||||
LoaderName = "test",
|
||||
VirtualPath = "~/bin"
|
||||
};
|
||||
|
||||
dependenciesFolder.StoreDescriptors(new [] { d });
|
||||
var e = dependenciesFolder.LoadDescriptors();
|
||||
Assert.That(e, Has.Count.EqualTo(1));
|
||||
Assert.That(e.First().Name, Is.EqualTo("name"));
|
||||
Assert.That(e.First().LoaderName, Is.EqualTo("test"));
|
||||
Assert.That(e.First().VirtualPath, Is.EqualTo("~/bin"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void StoreDescriptorsShouldNoOpIfNoChanges() {
|
||||
var clock = new StubClock();
|
||||
var appDataFolder = new StubAppDataFolder(clock);
|
||||
var dependenciesFolder = new DefaultDependenciesFolder(new StubCacheManager(), appDataFolder);
|
||||
|
||||
var d1 = new DependencyDescriptor {
|
||||
Name = "name1",
|
||||
LoaderName = "test1",
|
||||
VirtualPath = "~/bin1"
|
||||
};
|
||||
|
||||
var d2 = new DependencyDescriptor {
|
||||
Name = "name2",
|
||||
LoaderName = "test2",
|
||||
VirtualPath = "~/bin2"
|
||||
};
|
||||
|
||||
dependenciesFolder.StoreDescriptors(new[] { d1, d2 });
|
||||
var dateTime1 = appDataFolder.GetLastWriteTimeUtc(Path.Combine("Dependencies", "Dependencies.xml"));
|
||||
clock.Advance(TimeSpan.FromMinutes(1));
|
||||
|
||||
dependenciesFolder.StoreDescriptors(new[] { d2, d1 });
|
||||
var dateTime2 = appDataFolder.GetLastWriteTimeUtc(Path.Combine("Dependencies", "Dependencies.xml"));
|
||||
Assert.That(dateTime1, Is.EqualTo(dateTime2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void StoreDescriptorsShouldStoreIfChanges() {
|
||||
var clock = new StubClock();
|
||||
var appDataFolder = new StubAppDataFolder(clock);
|
||||
var dependenciesFolder = new DefaultDependenciesFolder(new StubCacheManager(), appDataFolder);
|
||||
|
||||
var d1 = new DependencyDescriptor {
|
||||
Name = "name1",
|
||||
LoaderName = "test1",
|
||||
VirtualPath = "~/bin1"
|
||||
};
|
||||
|
||||
var d2 = new DependencyDescriptor {
|
||||
Name = "name2",
|
||||
LoaderName = "test2",
|
||||
VirtualPath = "~/bin2"
|
||||
};
|
||||
|
||||
dependenciesFolder.StoreDescriptors(new[] { d1, d2 });
|
||||
var dateTime1 = appDataFolder.GetLastWriteTimeUtc(Path.Combine("Dependencies", "Dependencies.xml"));
|
||||
clock.Advance(TimeSpan.FromMinutes(1));
|
||||
|
||||
d1.LoaderName = "bar";
|
||||
|
||||
dependenciesFolder.StoreDescriptors(new[] { d2, d1 });
|
||||
var dateTime2 = appDataFolder.GetLastWriteTimeUtc(Path.Combine("Dependencies", "Dependencies.xml"));
|
||||
Assert.That(dateTime1 + TimeSpan.FromMinutes(1), Is.EqualTo(dateTime2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LoadDescriptorsShouldWorkAcrossInstances() {
|
||||
var clock = new StubClock();
|
||||
var appDataFolder = new StubAppDataFolder(clock);
|
||||
var dependenciesFolder = new DefaultDependenciesFolder(new StubCacheManager(), appDataFolder);
|
||||
|
||||
var d1 = new DependencyDescriptor {
|
||||
Name = "name1",
|
||||
LoaderName = "test1",
|
||||
VirtualPath = "~/bin1"
|
||||
};
|
||||
|
||||
var d2 = new DependencyDescriptor {
|
||||
Name = "name2",
|
||||
LoaderName = "test2",
|
||||
VirtualPath = "~/bin2"
|
||||
};
|
||||
|
||||
dependenciesFolder.StoreDescriptors(new[] { d1, d2 });
|
||||
|
||||
// Create a new instance over the same appDataFolder
|
||||
var dependenciesFolder2 = new DefaultDependenciesFolder(new StubCacheManager(), appDataFolder);
|
||||
|
||||
// Ensure descriptors were persisted properly
|
||||
var result = dependenciesFolder2.LoadDescriptors();
|
||||
Assert.That(result, Has.Count.EqualTo(2));
|
||||
Assert.That(result.Select(p => p.Name), Has.Some.EqualTo("name1"));
|
||||
Assert.That(result.Select(p => p.Name), Has.Some.EqualTo("name2"));
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,12 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Routing;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.Environment.Topology.Models;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.Environment.ShellBuilders.Models;
|
||||
using Orchard.Mvc.Routes;
|
||||
|
||||
namespace Orchard.Tests.Mvc.Routes {
|
||||
@@ -14,9 +12,9 @@ namespace Orchard.Tests.Mvc.Routes {
|
||||
public class StandardExtensionRouteProviderTests {
|
||||
[Test]
|
||||
public void ExtensionDisplayNameShouldBeUsedInBothStandardRoutes() {
|
||||
var topology = new ShellTopology {
|
||||
var blueprint = new ShellBlueprint {
|
||||
Controllers = new[] {
|
||||
new ControllerTopology {
|
||||
new ControllerBlueprint {
|
||||
AreaName ="Long.Name.Foo",
|
||||
Feature =new Feature {
|
||||
Descriptor=new FeatureDescriptor {
|
||||
@@ -26,7 +24,7 @@ namespace Orchard.Tests.Mvc.Routes {
|
||||
}
|
||||
}
|
||||
},
|
||||
new ControllerTopology {
|
||||
new ControllerBlueprint {
|
||||
AreaName ="Long.Name.Bar",
|
||||
Feature =new Feature {
|
||||
Descriptor=new FeatureDescriptor {
|
||||
@@ -38,7 +36,7 @@ namespace Orchard.Tests.Mvc.Routes {
|
||||
}
|
||||
}
|
||||
};
|
||||
var routeProvider = new StandardExtensionRouteProvider(topology);
|
||||
var routeProvider = new StandardExtensionRouteProvider(blueprint);
|
||||
|
||||
var routes = new List<RouteDescriptor>();
|
||||
routeProvider.GetRoutes(routes);
|
||||
@@ -58,38 +56,5 @@ namespace Orchard.Tests.Mvc.Routes {
|
||||
Assert.That(barAdmin.DataTokens["area"], Is.EqualTo("Long.Name.Bar"));
|
||||
Assert.That(barRoute.DataTokens["area"], Is.EqualTo("Long.Name.Bar"));
|
||||
}
|
||||
|
||||
public class StubExtensionManager : IExtensionManager {
|
||||
public IEnumerable<ExtensionDescriptor> AvailableExtensions() {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<Feature> LoadFeatures(IEnumerable<FeatureDescriptor> features) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<ExtensionEntry> ActiveExtensions_Obsolete() {
|
||||
yield return new ExtensionEntry {
|
||||
Descriptor = new ExtensionDescriptor {
|
||||
Name = "Long.Name.Foo",
|
||||
DisplayName = "Foo",
|
||||
}
|
||||
};
|
||||
yield return new ExtensionEntry {
|
||||
Descriptor = new ExtensionDescriptor {
|
||||
Name = "Long.Name.Bar",
|
||||
DisplayName = "Bar",
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void InstallExtension(string extensionType, HttpPostedFileBase extensionBundle) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void UninstallExtension(string extensionType, string extensionName) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -185,10 +185,11 @@
|
||||
<Compile Include="Data\StubLocator.cs" />
|
||||
<Compile Include="Environment\AutofacUtil\AutofacTests.cs" />
|
||||
<Compile Include="Environment\AutofacUtil\DynamicProxy2\DynamicProxyTests.cs" />
|
||||
<Compile Include="Environment\Extensions\ExtensionLoaderCoordinatorTests.cs" />
|
||||
<Compile Include="Environment\State\DefaultProcessingEngineTests.cs" />
|
||||
<Compile Include="Environment\RunningShellTableTests.cs" />
|
||||
<Compile Include="Environment\Utility\Build.cs" />
|
||||
<Compile Include="Environment\Configuration\AppDataFolderTests.cs" />
|
||||
<Compile Include="FileSystems\AppData\AppDataFolderTests.cs" />
|
||||
<Compile Include="Environment\Configuration\DefaultTenantManagerTests.cs" />
|
||||
<Compile Include="Environment\DefaultCompositionStrategyTests.cs" />
|
||||
<Compile Include="Environment\DefaultOrchardHostTests.cs" />
|
||||
@@ -196,14 +197,18 @@
|
||||
<Compile Include="Environment\OrchardStarterTests.cs" />
|
||||
<Compile Include="Environment\ShellBuilders\DefaultShellContainerFactoryTests.cs" />
|
||||
<Compile Include="Environment\ShellBuilders\DefaultShellContextFactoryTests.cs" />
|
||||
<Compile Include="FileSystems\Dependencies\DependenciesFolderTests.cs" />
|
||||
<Compile Include="Localization\CultureManagerTests.cs" />
|
||||
<Compile Include="Mvc\Routes\ShellRouteTests.cs" />
|
||||
<Compile Include="Mvc\Routes\UrlPrefixTests.cs" />
|
||||
<Compile Include="Stubs\StubFileSystem.cs" />
|
||||
<Compile Include="Stubs\StubAppDataFolder.cs" />
|
||||
<Compile Include="Stubs\StubVirtualPathMonitor.cs" />
|
||||
<Compile Include="Stubs\StubCacheManager.cs" />
|
||||
<Compile Include="Stubs\StubWebSiteFolder.cs" />
|
||||
<Compile Include="Utility\ContainerExtensions.cs" />
|
||||
<Compile Include="Environment\TestDependencies\TestDependency.cs" />
|
||||
<Compile Include="Environment\Topology\DefaultShellDescriptorCacheTests.cs" />
|
||||
<Compile Include="Environment\Blueprint\DefaultShellDescriptorCacheTests.cs" />
|
||||
<Compile Include="EventsTests.cs" />
|
||||
<Compile Include="Events\EventTests.cs" />
|
||||
<Compile Include="Environment\Extensions\ExtensionFoldersTests.cs" />
|
||||
@@ -270,6 +275,7 @@
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
77
src/Orchard.Tests/Stubs/StubAppDataFolder.cs
Normal file
77
src/Orchard.Tests/Stubs/StubAppDataFolder.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Orchard.Caching;
|
||||
using Orchard.FileSystems.AppData;
|
||||
using Orchard.Services;
|
||||
|
||||
namespace Orchard.Tests.Stubs {
|
||||
public class StubAppDataFolder : IAppDataFolder {
|
||||
private readonly IClock _clock;
|
||||
private readonly StubFileSystem _stubFileSystem;
|
||||
|
||||
public StubAppDataFolder(IClock clock) {
|
||||
_clock = clock;
|
||||
_stubFileSystem = new StubFileSystem(_clock);
|
||||
}
|
||||
|
||||
public StubFileSystem StubFileSystem {
|
||||
get { return _stubFileSystem; }
|
||||
}
|
||||
|
||||
public IEnumerable<string> ListFiles(string path) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<string> ListDirectories(string path) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool FileExists(string path) {
|
||||
return _stubFileSystem.GetFileEntry(path) != null;
|
||||
}
|
||||
|
||||
public string Combine(params string[] paths) {
|
||||
return Path.Combine(paths).Replace(Path.DirectorySeparatorChar, '/');
|
||||
}
|
||||
|
||||
public void CreateFile(string path, string content) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Stream CreateFile(string path) {
|
||||
return _stubFileSystem.CreateFile(path);
|
||||
}
|
||||
|
||||
public string ReadFile(string path) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Stream OpenFile(string path) {
|
||||
return _stubFileSystem.OpenFile(path);
|
||||
}
|
||||
|
||||
public void DeleteFile(string path) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void CreateDirectory(string path) {
|
||||
var entry = _stubFileSystem.CreateDirectoryEntry(path);
|
||||
}
|
||||
|
||||
public IVolatileToken WhenPathChanges(string path) {
|
||||
return _stubFileSystem.WhenPathChanges(path);
|
||||
}
|
||||
|
||||
public string MapPath(string path) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public DateTime GetLastWriteTimeUtc(string path) {
|
||||
var entry = _stubFileSystem.GetFileEntry(path);
|
||||
if (entry == null)
|
||||
throw new InvalidOperationException();
|
||||
return entry.LastWriteTime;
|
||||
}
|
||||
}
|
||||
}
|
@@ -3,13 +3,17 @@ using Orchard.Caching;
|
||||
|
||||
namespace Orchard.Tests.Stubs {
|
||||
public class StubCacheManager : ICacheManager {
|
||||
private readonly ICacheManager _defaultCacheManager;
|
||||
|
||||
public StubCacheManager() {
|
||||
_defaultCacheManager = new DefaultCacheManager(this.GetType(), new DefaultCacheHolder());
|
||||
}
|
||||
public TResult Get<TKey, TResult>(TKey key, Func<AcquireContext<TKey>, TResult> acquire) {
|
||||
var cache = new Cache<TKey, TResult>();
|
||||
return cache.Get(key, acquire);
|
||||
return _defaultCacheManager.Get(key, acquire);
|
||||
}
|
||||
|
||||
public ICache<TKey, TResult> GetCache<TKey, TResult>() {
|
||||
throw new NotImplementedException();
|
||||
return _defaultCacheManager.GetCache<TKey, TResult>();
|
||||
}
|
||||
}
|
||||
}
|
364
src/Orchard.Tests/Stubs/StubFileSystem.cs
Normal file
364
src/Orchard.Tests/Stubs/StubFileSystem.cs
Normal file
@@ -0,0 +1,364 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Orchard.Caching;
|
||||
using Orchard.Services;
|
||||
|
||||
namespace Orchard.Tests.Stubs {
|
||||
public class StubFileSystem {
|
||||
public class Entry {
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
public class DirectoryEntry : Entry {
|
||||
private readonly IClock _clock;
|
||||
|
||||
public DirectoryEntry(IClock clock) {
|
||||
_clock = clock;
|
||||
Entries = new List<Entry>();
|
||||
}
|
||||
|
||||
public IList<Entry> Entries { get; private set; }
|
||||
|
||||
public Entry GetEntry(string name) {
|
||||
if (string.IsNullOrEmpty(name))
|
||||
throw new ArgumentException();
|
||||
|
||||
if (name.Contains(Path.DirectorySeparatorChar) || name.Contains(Path.AltDirectorySeparatorChar))
|
||||
throw new ArgumentException();
|
||||
|
||||
return Entries.FirstOrDefault(e => StringComparer.OrdinalIgnoreCase.Equals(e.Name, name));
|
||||
}
|
||||
|
||||
public DirectoryEntry CreateDirectory(string name) {
|
||||
var entry = GetEntry(name);
|
||||
|
||||
if (entry == null) {
|
||||
entry = new DirectoryEntry(_clock) { Name = name };
|
||||
this.Entries.Add(entry);
|
||||
}
|
||||
|
||||
if (!(entry is DirectoryEntry)) {
|
||||
throw new InvalidOperationException(string.Format("Can't create directory \"{0}\": not a directory.", name));
|
||||
}
|
||||
|
||||
return (DirectoryEntry)entry;
|
||||
}
|
||||
|
||||
public FileEntry CreateFile(string name) {
|
||||
var entry = GetEntry(name);
|
||||
|
||||
if (entry == null) {
|
||||
entry = new FileEntry (_clock) { Name = name };
|
||||
this.Entries.Add(entry);
|
||||
}
|
||||
|
||||
if (!(entry is FileEntry)) {
|
||||
throw new InvalidOperationException(string.Format("Can't create file \"{0}\": not a file.", name));
|
||||
}
|
||||
|
||||
return (FileEntry)entry;
|
||||
}
|
||||
}
|
||||
|
||||
public class FileEntry : Entry {
|
||||
private readonly IClock _clock;
|
||||
|
||||
public FileEntry(IClock clock) {
|
||||
_clock = clock;
|
||||
LastWriteTime = _clock.UtcNow;
|
||||
Content = new List<byte>();
|
||||
}
|
||||
|
||||
public List<byte> Content { get; private set; }
|
||||
public DateTime LastWriteTime { get; set; }
|
||||
}
|
||||
|
||||
public class Token : IVolatileToken {
|
||||
private readonly StubFileSystem _stubFileSystem;
|
||||
private readonly string _path;
|
||||
private bool _isCurrent;
|
||||
|
||||
public Token(StubFileSystem stubFileSystem, string path) {
|
||||
_stubFileSystem = stubFileSystem;
|
||||
_path = path;
|
||||
_isCurrent = true;
|
||||
}
|
||||
|
||||
public bool IsCurrent { get { return _isCurrent; } }
|
||||
|
||||
public void OnChange() {
|
||||
_isCurrent = false;
|
||||
_stubFileSystem.DetachToken(_path);
|
||||
}
|
||||
}
|
||||
|
||||
public class FileEntryWriteStream : Stream {
|
||||
private readonly Token _token;
|
||||
private readonly FileEntry _entry;
|
||||
private readonly IClock _clock;
|
||||
private long _position;
|
||||
|
||||
public FileEntryWriteStream(Token token, StubFileSystem.FileEntry entry, IClock clock) {
|
||||
_token = token;
|
||||
_entry = entry;
|
||||
_clock = clock;
|
||||
}
|
||||
|
||||
public override void Flush() {
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void SetLength(long value) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public class ArrayWrapper<T> : ICollection<T> {
|
||||
private readonly T[] _buffer;
|
||||
private readonly int _offset;
|
||||
private readonly int _count;
|
||||
|
||||
public ArrayWrapper(T[] buffer, int offset, int count) {
|
||||
_buffer = buffer;
|
||||
_offset = offset;
|
||||
_count = count;
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator() {
|
||||
for (int i = _offset; i < _count; i++)
|
||||
yield return _buffer[i];
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() {
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public void Add(T item) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Clear() {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool Contains(T item) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex) {
|
||||
Array.Copy(_buffer, _offset, array, arrayIndex, _count);
|
||||
}
|
||||
|
||||
public bool Remove(T item) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int Count {
|
||||
get { return _count; }
|
||||
}
|
||||
|
||||
public bool IsReadOnly {
|
||||
get { return true; }
|
||||
}
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count) {
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
var wrapper = new ArrayWrapper<byte>(buffer, offset, count);
|
||||
_entry.Content.AddRange(wrapper);
|
||||
|
||||
_entry.LastWriteTime = _clock.UtcNow;
|
||||
if (_token != null)
|
||||
_token.OnChange();
|
||||
_position += count;
|
||||
}
|
||||
|
||||
public override bool CanRead {
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override bool CanSeek {
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override bool CanWrite {
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override long Length {
|
||||
get { return _entry.Content.Count; }
|
||||
}
|
||||
|
||||
public override long Position {
|
||||
get { return _position; }
|
||||
set { throw new NotImplementedException(); }
|
||||
}
|
||||
}
|
||||
|
||||
public class FileEntryReadStream : Stream {
|
||||
private readonly FileEntry _entry;
|
||||
private readonly IClock _clock;
|
||||
private int _position;
|
||||
|
||||
public FileEntryReadStream(FileEntry entry, IClock clock) {
|
||||
_entry = entry;
|
||||
_clock = clock;
|
||||
}
|
||||
|
||||
public override void Flush() {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin) {
|
||||
switch (origin) {
|
||||
case SeekOrigin.Begin:
|
||||
_position = (int)offset;
|
||||
break;
|
||||
case SeekOrigin.Current:
|
||||
_position += (int) offset;
|
||||
break;
|
||||
case SeekOrigin.End:
|
||||
_position = _entry.Content.Count - (int) offset;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("origin");
|
||||
}
|
||||
return _position;
|
||||
}
|
||||
|
||||
public override void SetLength(long value) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count) {
|
||||
int remaingCount = _entry.Content.Count - _position;
|
||||
count = Math.Min(count, remaingCount);
|
||||
|
||||
_entry.Content.CopyTo(_position, buffer, offset, count);
|
||||
|
||||
_position += count;
|
||||
return count;
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool CanRead {
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool CanSeek {
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool CanWrite {
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override long Length {
|
||||
get { return _entry.Content.Count; }
|
||||
}
|
||||
|
||||
public override long Position {
|
||||
get { return _position; }
|
||||
set { _position = (int) value; }
|
||||
}
|
||||
}
|
||||
|
||||
private readonly IClock _clock;
|
||||
private readonly DirectoryEntry _root;
|
||||
private readonly Dictionary<string, Weak<Token>> _tokens;
|
||||
|
||||
public StubFileSystem(IClock clock) {
|
||||
_clock = clock;
|
||||
_root = new DirectoryEntry(_clock);
|
||||
_tokens = new Dictionary<string, Weak<Token>>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private DirectoryEntry GetDirectoryEntry(string path) {
|
||||
path = path.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
||||
var current = _root;
|
||||
foreach (var name in path.Split(Path.DirectorySeparatorChar)) {
|
||||
current = current.GetEntry(name) as StubFileSystem.DirectoryEntry;
|
||||
if (current == null)
|
||||
break;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
public DirectoryEntry CreateDirectoryEntry(string path) {
|
||||
path = path.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
||||
var current = _root;
|
||||
foreach (var name in path.Split(Path.DirectorySeparatorChar)) {
|
||||
current = current.CreateDirectory(name);
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
|
||||
public FileEntry GetFileEntry(string path) {
|
||||
var directoryName = Path.GetDirectoryName(path);
|
||||
var fileName = Path.GetFileName(path);
|
||||
|
||||
var directory = GetDirectoryEntry(directoryName);
|
||||
if (directory == null)
|
||||
return null;
|
||||
|
||||
return directory.GetEntry(fileName) as StubFileSystem.FileEntry;
|
||||
}
|
||||
|
||||
public FileEntry CreateFileEntry(string path) {
|
||||
var directoryName = Path.GetDirectoryName(path);
|
||||
var fileName = Path.GetFileName(path);
|
||||
|
||||
return CreateDirectoryEntry(directoryName).CreateFile(fileName);
|
||||
}
|
||||
|
||||
public IVolatileToken WhenPathChanges(string path) {
|
||||
Token token = GetToken(path);
|
||||
|
||||
if (token == null) {
|
||||
token = new Token(this, path);
|
||||
_tokens.Add(path, new Weak<Token>(token));
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
private Token GetToken(string path) {
|
||||
Token token = null;
|
||||
Weak<Token> weakRef;
|
||||
if (_tokens.TryGetValue(path, out weakRef))
|
||||
token = weakRef.Target;
|
||||
return token;
|
||||
}
|
||||
|
||||
private void DetachToken(string path) {
|
||||
_tokens.Remove(path);
|
||||
}
|
||||
|
||||
public Stream CreateFile(string path) {
|
||||
var entry = CreateFileEntry(path);
|
||||
return new FileEntryWriteStream(GetToken(path), entry, _clock);
|
||||
}
|
||||
|
||||
public Stream OpenFile(string path) {
|
||||
var entry = GetFileEntry(path);
|
||||
if (entry == null)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
return new FileEntryReadStream(entry, _clock);
|
||||
}
|
||||
}
|
||||
}
|
18
src/Orchard.Tests/Stubs/StubVirtualPathMonitor.cs
Normal file
18
src/Orchard.Tests/Stubs/StubVirtualPathMonitor.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using Orchard.Caching;
|
||||
using Orchard.FileSystems.VirtualPath;
|
||||
|
||||
namespace Orchard.Tests.Stubs {
|
||||
public class StubVirtualPathMonitor : IVirtualPathMonitor {
|
||||
public class Token : IVolatileToken {
|
||||
public bool IsCurrent { get; set; }
|
||||
}
|
||||
public IVolatileToken WhenPathChanges(string virtualPath) {
|
||||
return new Token();
|
||||
}
|
||||
|
||||
public void WhenPathChanges(string virtualPath, Action action) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -21,7 +22,15 @@ namespace Orchard.Tests.Stubs {
|
||||
}
|
||||
|
||||
public IVolatileToken WhenPathChanges(string path) {
|
||||
return new WebSiteFolder.Token(path);
|
||||
return new Token {IsCurrent = true};
|
||||
}
|
||||
|
||||
public void WhenPathChanges(string path, Action action) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public class Token : IVolatileToken {
|
||||
public bool IsCurrent { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
@@ -3,6 +3,7 @@ using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using NUnit.Framework;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Security;
|
||||
using Orchard.Security.Permissions;
|
||||
using Orchard.Tests.Stubs;
|
||||
@@ -71,9 +72,10 @@ namespace Orchard.Tests.UI.Navigation {
|
||||
public string MenuName { get { return "admin"; } }
|
||||
|
||||
public void GetNavigation(NavigationBuilder builder) {
|
||||
var T = NullLocalizer.Instance;
|
||||
builder
|
||||
.Add("Foo", "1.0", x => x.Action("foo"))
|
||||
.Add("Bar", "2.0", x => x.Add("Frap", "1.b"));
|
||||
.Add(T("Foo"), "1.0", x => x.Action("foo"))
|
||||
.Add(T("Bar"), "2.0", x => x.Add(T("Frap"), "1.b"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,9 +83,10 @@ namespace Orchard.Tests.UI.Navigation {
|
||||
public string MenuName { get { return "admin"; } }
|
||||
|
||||
public void GetNavigation(NavigationBuilder builder) {
|
||||
var T = NullLocalizer.Instance;
|
||||
builder
|
||||
.Add("Frap", "3.0", x => x.Action("foo"))
|
||||
.Add("Bar", "4.0", x => x.Add("Quad", "1.a"));
|
||||
.Add(T("Frap"), "3.0", x => x.Action("foo"))
|
||||
.Add(T("Bar"), "4.0", x => x.Add(T("Quad"), "1.a"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -9,12 +9,12 @@ namespace Orchard.Tests.UI.Notify {
|
||||
[Test]
|
||||
public void MessageServiceCanAccumulateWarningsAndErrorsToReturn() {
|
||||
INotifier notifier = new Notifier();
|
||||
notifier.Warning("Hello world");
|
||||
notifier.Information("More Info");
|
||||
notifier.Error("Boom");
|
||||
|
||||
Localizer T = NullLocalizer.Instance;
|
||||
|
||||
notifier.Warning(T("Hello world"));
|
||||
notifier.Information(T("More Info"));
|
||||
notifier.Error(T("Boom"));
|
||||
|
||||
Assert.That(notifier.List(), Has.Count.EqualTo(3));
|
||||
Assert.That(notifier.List(), Has.Some.Property("Message").EqualTo(T("Hello world")));
|
||||
Assert.That(notifier.List(), Has.Some.Property("Message").EqualTo(T("More Info")));
|
||||
|
@@ -23,7 +23,8 @@ namespace Orchard.Tests.UI.Notify {
|
||||
public void AfterActionExecutedMessagesShouldAppearInTempData() {
|
||||
var sink = new Notifier();
|
||||
var filter = new NotifyFilter(sink);
|
||||
sink.Information("Hello world");
|
||||
var T = NullLocalizer.Instance;
|
||||
sink.Information(T("Hello world"));
|
||||
|
||||
var executedContext = BuildContext();
|
||||
filter.OnActionExecuted(executedContext);
|
||||
@@ -47,7 +48,8 @@ namespace Orchard.Tests.UI.Notify {
|
||||
public void NewMessagesAreConcatinated() {
|
||||
var sink = new Notifier();
|
||||
var filter = new NotifyFilter(sink);
|
||||
sink.Error("Boom");
|
||||
var T = NullLocalizer.Instance;
|
||||
sink.Error(T("Boom"));
|
||||
|
||||
var executedContext = BuildContext();
|
||||
executedContext.Controller.TempData.Add("messages", "dont-destroy");
|
||||
@@ -60,7 +62,8 @@ namespace Orchard.Tests.UI.Notify {
|
||||
public void TempDataBuildsMessagesWhenResultExecutingIsBaseViewModel() {
|
||||
var sink = new Notifier();
|
||||
var filter = new NotifyFilter(sink);
|
||||
sink.Information("Working");
|
||||
var T = NullLocalizer.Instance;
|
||||
sink.Information(T("Working"));
|
||||
|
||||
var model = new BaseViewModel();
|
||||
|
||||
@@ -74,8 +77,6 @@ namespace Orchard.Tests.UI.Notify {
|
||||
filter.OnActionExecuted(context);
|
||||
filter.OnResultExecuting(new ResultExecutingContext(context, context.Result));
|
||||
|
||||
var T = NullLocalizer.Instance;
|
||||
|
||||
Assert.That(model.Messages, Is.Not.Null);
|
||||
Assert.That(model.Messages, Has.Count.EqualTo(2));
|
||||
Assert.That(model.Messages, Has.Some.Property("Message").EqualTo(T("dont-destroy")));
|
||||
|
@@ -83,10 +83,10 @@ msgstr "Not authorized to manage settings"
|
||||
msgid "Settings updated"
|
||||
msgstr "Settings updated"
|
||||
|
||||
#: ~/Core/Settings/Topology/ShellDescriptorManager.cs
|
||||
#| msgid : "Invalid serial number for shell topology"
|
||||
msgid "Invalid serial number for shell topology"
|
||||
msgstr "Invalid serial number for shell topology"
|
||||
#: ~/Core/Settings/Descriptor/ShellDescriptorManager.cs
|
||||
#| msgid : "Invalid serial number for shell descriptor"
|
||||
msgid "Invalid serial number for shell descriptor"
|
||||
msgstr "Invalid serial number for shell descriptor"
|
||||
|
||||
#: ~/Core/Settings/Views/Admin/Index.ascx
|
||||
#| msgid : "Manage Settings"
|
||||
|
@@ -83,9 +83,9 @@ msgstr "Non autorisé à gérer la configuration"
|
||||
msgid "Settings updated"
|
||||
msgstr "Configuration mise à jour"
|
||||
|
||||
#: ~/Core/Settings/Topology/ShellDescriptorManager.cs
|
||||
#| msgid : "Invalid serial number for shell topology"
|
||||
msgid "Invalid serial number for shell topology"
|
||||
#: ~/Core/Settings/Descriptor/ShellDescriptorManager.cs
|
||||
#| msgid : "Invalid serial number for shell descriptor"
|
||||
msgid "Invalid serial number for shell descriptor"
|
||||
msgstr "Numéro de série de topologie de shell invalide."
|
||||
|
||||
#: ~/Core/Settings/Views/Admin/Index.ascx
|
||||
|
@@ -38,7 +38,7 @@ namespace Orchard.Core.Common.Drivers {
|
||||
updater.TryUpdateModel(model, Prefix, null, null);
|
||||
|
||||
if (!_routableService.IsSlugValid(part.Slug)){
|
||||
updater.AddModelError("Routable.Slug", T("Please do not use any of the following characters in your slugs: \"/\", \":\", \"?\", \"#\", \"[\", \"]\", \"@\", \"!\", \"$\", \"&\", \"'\", \"(\", \")\", \"*\", \"+\", \",\", \";\", \"=\". No spaces are allowed (please use dashes or underscores instead).").ToString());
|
||||
updater.AddModelError("Routable.Slug", T("Please do not use any of the following characters in your slugs: \"/\", \":\", \"?\", \"#\", \"[\", \"]\", \"@\", \"!\", \"$\", \"&\", \"'\", \"(\", \")\", \"*\", \"+\", \",\", \";\", \"=\". No spaces are allowed (please use dashes or underscores instead)."));
|
||||
}
|
||||
|
||||
string originalSlug = part.Slug;
|
||||
|
@@ -0,0 +1,45 @@
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.Core.Common.Fields;
|
||||
using Orchard.Core.Common.ViewModels;
|
||||
|
||||
namespace Orchard.Core.Common.Drivers {
|
||||
[UsedImplicitly]
|
||||
public class TextContentFieldDriver : ContentFieldDriver<TextContentField> {
|
||||
public IOrchardServices Services { get; set; }
|
||||
private const string TemplateName = "Fields/Common.TextContentField";
|
||||
|
||||
public TextContentFieldDriver(IOrchardServices services) {
|
||||
Services = services;
|
||||
}
|
||||
|
||||
protected override string Prefix {
|
||||
get { return "TextContentField"; }
|
||||
}
|
||||
|
||||
protected override DriverResult Display(TextContentField field, string displayType) {
|
||||
var model = new TextContentFieldDisplayViewModel { Text = field };
|
||||
|
||||
return ContentFieldTemplate(model, TemplateName, Prefix);
|
||||
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(TextContentField field) {
|
||||
var model = BuildEditorViewModel(field);
|
||||
return ContentFieldTemplate(model, TemplateName, Prefix).Location("primary", "5");
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(TextContentField field, IUpdateModel updater) {
|
||||
var model = BuildEditorViewModel(field);
|
||||
updater.TryUpdateModel(model, Prefix, null, null);
|
||||
return ContentFieldTemplate(model, TemplateName, Prefix).Location("primary", "5");
|
||||
}
|
||||
|
||||
private static TextContentFieldEditorViewModel BuildEditorViewModel(TextContentField field) {
|
||||
return new TextContentFieldEditorViewModel {
|
||||
TextContentField = field
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
10
src/Orchard.Web/Core/Common/Fields/TextContentField.cs
Normal file
10
src/Orchard.Web/Core/Common/Fields/TextContentField.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using Orchard.ContentManagement;
|
||||
|
||||
namespace Orchard.Core.Common.Fields {
|
||||
public class TextContentField : ContentField {
|
||||
public string TextField {
|
||||
get { return Getter("text"); }
|
||||
set { Setter("text", value); }
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +1,9 @@
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Core.Common.ViewModels;
|
||||
using Orchard.Data;
|
||||
using Orchard.Localization;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.ContentManagement.ViewModels;
|
||||
using Orchard.Security;
|
||||
using Orchard.Services;
|
||||
|
||||
@@ -37,10 +35,10 @@ namespace Orchard.Core.Common.Handlers {
|
||||
Filters.Add(StorageFilter.For(commonRepository));
|
||||
Filters.Add(StorageFilter.For(commonVersionRepository));
|
||||
|
||||
OnActivated<CommonAspect>(PropertySetHandlers);
|
||||
OnActivated<CommonAspect>(AssignCreatingOwner);
|
||||
OnActivated<ContentPart<CommonRecord>>(AssignCreatingDates);
|
||||
OnActivated<ContentPart<CommonVersionRecord>>(AssignCreatingDates);
|
||||
OnInitializing<CommonAspect>(PropertySetHandlers);
|
||||
OnInitializing<CommonAspect>(AssignCreatingOwner);
|
||||
OnInitializing<ContentPart<CommonRecord>>(AssignCreatingDates);
|
||||
OnInitializing<ContentPart<CommonVersionRecord>>(AssignCreatingDates);
|
||||
|
||||
OnLoaded<CommonAspect>(LazyLoadHandlers);
|
||||
|
||||
@@ -67,20 +65,20 @@ namespace Orchard.Core.Common.Handlers {
|
||||
public Localizer T { get; set; }
|
||||
|
||||
|
||||
void AssignCreatingOwner(ActivatedContentContext context, CommonAspect part) {
|
||||
void AssignCreatingOwner(InitializingContentContext context, CommonAspect part) {
|
||||
// and use the current user as Owner
|
||||
if (part.Record.OwnerId == 0) {
|
||||
part.Owner = _authenticationService.GetAuthenticatedUser();
|
||||
}
|
||||
}
|
||||
|
||||
void AssignCreatingDates(ActivatedContentContext context, ContentPart<CommonRecord> part) {
|
||||
void AssignCreatingDates(InitializingContentContext 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) {
|
||||
void AssignCreatingDates(InitializingContentContext context, ContentPart<CommonVersionRecord> part) {
|
||||
// assign default create/modified dates
|
||||
part.Record.CreatedUtc = _clock.UtcNow;
|
||||
part.Record.ModifiedUtc = _clock.UtcNow;
|
||||
@@ -124,7 +122,7 @@ namespace Orchard.Core.Common.Handlers {
|
||||
aspect.ContainerField.Loader(() => aspect.Record.Container == null ? null : _contentManager.Get(aspect.Record.Container.Id));
|
||||
}
|
||||
|
||||
static void PropertySetHandlers(ActivatedContentContext context, CommonAspect aspect) {
|
||||
static void PropertySetHandlers(InitializingContentContext context, CommonAspect aspect) {
|
||||
// add handlers that will update records when aspect properties are set
|
||||
|
||||
aspect.OwnerField.Setter(user => {
|
||||
|
@@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
|
||||
namespace Orchard.Core.Common.Handlers {
|
||||
public class TextContentFieldHandler : ContentFieldHandler {
|
||||
public TextContentFieldHandler(IEnumerable<IContentFieldDriver> contentFieldDrivers) : base(contentFieldDrivers) {}
|
||||
}
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
using Orchard.Core.Common.Fields;
|
||||
|
||||
namespace Orchard.Core.Common.ViewModels {
|
||||
public class TextContentFieldDisplayViewModel {
|
||||
public TextContentField Text { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Orchard.Core.Common.Fields;
|
||||
|
||||
namespace Orchard.Core.Common.ViewModels {
|
||||
public class TextContentFieldEditorViewModel {
|
||||
public TextContentField TextContentField { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Text {
|
||||
get { return TextContentField.TextField; }
|
||||
set { TextContentField.TextField = value; }
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<TextContentFieldDisplayViewModel>" %>
|
||||
<%@ Import Namespace="Orchard.Core.Common.ViewModels"%>
|
||||
<%=Model.Text %>
|
@@ -0,0 +1,7 @@
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<TextContentFieldEditorViewModel>" %>
|
||||
<%@ Import Namespace="Orchard.Core.Common.ViewModels"%>
|
||||
<fieldset>
|
||||
<%: Html.LabelFor(m=>m.Text) %>
|
||||
<%: Html.EditorFor(m=>m.Text) %>
|
||||
<%: Html.ValidationMessageFor(m=>m.Text) %>
|
||||
</fieldset>
|
@@ -1,19 +1,37 @@
|
||||
using Orchard.Localization;
|
||||
using Orchard.Security;
|
||||
using System.Linq;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.Localization;
|
||||
using Orchard.UI.Navigation;
|
||||
|
||||
namespace Orchard.Core.Contents {
|
||||
public class AdminMenu : INavigationProvider {
|
||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||
private readonly IContentManager _contentManager;
|
||||
|
||||
public AdminMenu(IContentDefinitionManager contentDefinitionManager, IContentManager contentManager) {
|
||||
_contentDefinitionManager = contentDefinitionManager;
|
||||
_contentManager = contentManager;
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
public string MenuName { get { return "admin"; } }
|
||||
|
||||
public void GetNavigation(NavigationBuilder builder) {
|
||||
builder.Add(T("Content"), "1",
|
||||
menu => {
|
||||
menu.Add(T("Create"), "1.1", item => item.Action("Create", "Admin", new { area = "Contents" }));
|
||||
menu.Add(T("List"), "1.2", item => item.Action("List", "Admin", new { area = "Contents" }));
|
||||
menu.Add(T("Types"), "1.3", item => item.Action("Types", "Admin", new { area = "Contents" }));
|
||||
});
|
||||
var contentTypeDefinitions = _contentDefinitionManager.ListTypeDefinitions().OrderBy(d => d.Name);
|
||||
|
||||
builder.Add(T("Content"), "1", menu => {
|
||||
menu.Add(T("Manage Content"), "1.2", item => item.Action("List", "Admin", new {area = "Contents"}));
|
||||
//foreach (var contentTypeDefinition in contentTypeDefinitions) {
|
||||
// var ci = _contentManager.New(contentTypeDefinition.Name);
|
||||
// var cim = _contentManager.GetItemMetadata(ci);
|
||||
// var createRouteValues = cim.CreateRouteValues;
|
||||
// if (createRouteValues.Any())
|
||||
// menu.Add(T("Create New {0}", contentTypeDefinition.DisplayName), "1.3", item => item.Action(cim.CreateRouteValues["Action"] as string, cim.CreateRouteValues["Controller"] as string, cim.CreateRouteValues));
|
||||
//}
|
||||
});
|
||||
builder.Add(T("Site Configuration"), "11",
|
||||
menu => menu.Add(T("Content Types"), "3", item => item.Action("Index", "Admin", new { area = "Contents" })));
|
||||
}
|
||||
}
|
||||
}
|
10
src/Orchard.Web/Core/Contents/ContentTypeDefinitionStub.cs
Normal file
10
src/Orchard.Web/Core/Contents/ContentTypeDefinitionStub.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Orchard.Core.Contents {
|
||||
public class ContentTypeDefinitionStub {
|
||||
[StringLength(128)]
|
||||
public string Name { get; set; }
|
||||
[Required, StringLength(1024)]
|
||||
public string DisplayName { get; set; }
|
||||
}
|
||||
}
|
@@ -4,7 +4,7 @@ using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.Records;
|
||||
using Orchard.Core.Contents.Services;
|
||||
using Orchard.Core.Contents.ViewModels;
|
||||
using Orchard.Data;
|
||||
using Orchard.Localization;
|
||||
@@ -16,37 +16,72 @@ namespace Orchard.Core.Contents.Controllers {
|
||||
[ValidateInput(false)]
|
||||
public class AdminController : Controller, IUpdateModel {
|
||||
private readonly INotifier _notifier;
|
||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||
private readonly IContentDefinitionService _contentDefinitionService;
|
||||
private readonly IContentManager _contentManager;
|
||||
private readonly ITransactionManager _transactionManager;
|
||||
|
||||
public AdminController(
|
||||
IOrchardServices orchardServices,
|
||||
INotifier notifier,
|
||||
IContentDefinitionManager contentDefinitionManager,
|
||||
IContentDefinitionService contentDefinitionService,
|
||||
IContentManager contentManager,
|
||||
ITransactionManager transactionManager) {
|
||||
Services = orchardServices;
|
||||
_notifier = notifier;
|
||||
_contentDefinitionManager = contentDefinitionManager;
|
||||
_contentDefinitionService = contentDefinitionService;
|
||||
_contentManager = contentManager;
|
||||
_transactionManager = transactionManager;
|
||||
T = NullLocalizer.Instance;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
|
||||
public IOrchardServices Services { get; private set; }
|
||||
public Localizer T { get; set; }
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
#region Types
|
||||
|
||||
public ActionResult Index() {
|
||||
return Types();
|
||||
}
|
||||
|
||||
public ActionResult Types() {
|
||||
return View("Types", new ContentTypeListViewModel {
|
||||
Types = _contentDefinitionManager.ListTypeDefinitions()
|
||||
return View("Types", new ListContentTypesViewModel {
|
||||
Types = _contentDefinitionService.GetTypeDefinitions()
|
||||
});
|
||||
}
|
||||
|
||||
public ActionResult List(ListContentViewModel model) {
|
||||
public ActionResult CreateType(CreateTypeViewModel viewModel) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.CreateContentType, T("Not allowed to create a content type.")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("CreateType")]
|
||||
public ActionResult CreateTypePOST(CreateTypeViewModel viewModel) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.CreateContentType, T("Not allowed to create a content type.")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var model = new ContentTypeDefinitionStub();
|
||||
TryUpdateModel(model);
|
||||
|
||||
if (!ModelState.IsValid) {
|
||||
Services.TransactionManager.Cancel();
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
_contentDefinitionService.AddTypeDefinition(model);
|
||||
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Content
|
||||
#endregion
|
||||
|
||||
public ActionResult List(ListContentsViewModel model) {
|
||||
const int pageSize = 20;
|
||||
var skip = (Math.Max(model.Page ?? 0, 1) - 1) * pageSize;
|
||||
|
||||
@@ -63,8 +98,8 @@ namespace Orchard.Core.Contents.Controllers {
|
||||
return View("List", model);
|
||||
}
|
||||
|
||||
private ListContentViewModel.Entry BuildEntry(ContentItem contentItem) {
|
||||
var entry = new ListContentViewModel.Entry {
|
||||
private ListContentsViewModel.Entry BuildEntry(ContentItem contentItem) {
|
||||
var entry = new ListContentsViewModel.Entry {
|
||||
ContentItem = contentItem,
|
||||
ContentItemMetadata = _contentManager.GetItemMetadata(contentItem),
|
||||
ViewModel = _contentManager.BuildDisplayModel(contentItem, "List"),
|
||||
@@ -84,8 +119,8 @@ namespace Orchard.Core.Contents.Controllers {
|
||||
}
|
||||
|
||||
ActionResult CreatableTypeList() {
|
||||
var model = new ContentTypeListViewModel {
|
||||
Types = _contentDefinitionManager.ListTypeDefinitions()
|
||||
var model = new ListContentTypesViewModel {
|
||||
Types = _contentDefinitionService.GetTypeDefinitions()
|
||||
};
|
||||
|
||||
return View("CreatableTypeList", model);
|
||||
@@ -107,6 +142,7 @@ namespace Orchard.Core.Contents.Controllers {
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult Create(CreateItemViewModel model) {
|
||||
//todo: need to integrate permissions into generic content management
|
||||
var contentItem = _contentManager.New(model.Id);
|
||||
model.Content = _contentManager.UpdateEditorModel(contentItem, this);
|
||||
if (ModelState.IsValid) {
|
||||
|
@@ -15,6 +15,7 @@ namespace Orchard.Core.Contents.Controllers {
|
||||
_contentManager = contentManager;
|
||||
}
|
||||
|
||||
// /Contents/Item/Display/72
|
||||
public ActionResult Display(int id) {
|
||||
var contentItem = _contentManager.Get(id, VersionOptions.Published);
|
||||
|
||||
@@ -25,6 +26,8 @@ namespace Orchard.Core.Contents.Controllers {
|
||||
return View("Display", model);
|
||||
}
|
||||
|
||||
// /Contents/Item/Preview/72
|
||||
// /Contents/Item/Preview/72?version=5
|
||||
public ActionResult Preview(int id, int? version) {
|
||||
var versionOptions = VersionOptions.Latest;
|
||||
if (version != null) {
|
||||
|
@@ -1,13 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Routing;
|
||||
using System.Web.Routing;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
|
||||
namespace Orchard.Core.Contents.Handlers {
|
||||
public class ContentsModuleHandler : ContentHandlerBase {
|
||||
public override void GetContentItemMetadata(GetContentItemMetadataContext context) {
|
||||
if (context.Metadata.CreateRouteValues == null) {
|
||||
context.Metadata.CreateRouteValues = new RouteValueDictionary {
|
||||
{"Area", "Contents"},
|
||||
{"Controller", "Item"},
|
||||
{"Action", "Create"}
|
||||
};
|
||||
}
|
||||
if (context.Metadata.EditorRouteValues == null) {
|
||||
context.Metadata.EditorRouteValues = new RouteValueDictionary {
|
||||
{"Area", "Contents"},
|
||||
|
@@ -7,5 +7,5 @@ orchardversion: 0.1.2010.0312
|
||||
description: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas consectetur consequat risus, vel blandit arcu tincidunt eget. Nam rutrum nulla vestibulum dolor dapibus sagittis. Vivamus convallis faucibus accumsan. Suspendisse sapien enim, cursus at dignissim a, sollicitudin sit amet est. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec sed urna magna, in luctus nulla. Pellentesque erat ipsum, convallis sed molestie tempus, mattis vel leo metus.
|
||||
features:
|
||||
Contents:
|
||||
Description: Default controllers for some content types.
|
||||
Description: Default custom content type definition, creation and management.
|
||||
Category: Core
|
27
src/Orchard.Web/Core/Contents/Permissions.cs
Normal file
27
src/Orchard.Web/Core/Contents/Permissions.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Security.Permissions;
|
||||
|
||||
namespace Orchard.Core.Contents {
|
||||
public class Permissions : IPermissionProvider {
|
||||
public static readonly Permission CreateContentType = new Permission { Name = "CreateContentType", Description = "Create custom content type." };
|
||||
|
||||
public string ModuleName {
|
||||
get { return "Contents"; }
|
||||
}
|
||||
|
||||
public IEnumerable<Permission> GetPermissions() {
|
||||
return new Permission[] {
|
||||
CreateContentType,
|
||||
};
|
||||
}
|
||||
|
||||
public IEnumerable<PermissionStereotype> GetDefaultStereotypes() {
|
||||
return new[] {
|
||||
new PermissionStereotype {
|
||||
Name = "Administrator",
|
||||
Permissions = new[] {CreateContentType}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.Localization;
|
||||
using Orchard.UI.Notify;
|
||||
|
||||
namespace Orchard.Core.Contents.Services {
|
||||
public class ContentDefinitionService : IContentDefinitionService {
|
||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||
|
||||
public ContentDefinitionService(IOrchardServices services, IContentDefinitionManager contentDefinitionManager) {
|
||||
Services = services;
|
||||
_contentDefinitionManager = contentDefinitionManager;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public IOrchardServices Services { get; set; }
|
||||
public Localizer T { get; set; }
|
||||
|
||||
public IEnumerable<ContentTypeDefinition> GetTypeDefinitions() {
|
||||
return _contentDefinitionManager.ListTypeDefinitions();
|
||||
}
|
||||
|
||||
public ContentTypeDefinition GetTypeDefinition(string name) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void AddTypeDefinition(ContentTypeDefinitionStub definitionStub) {
|
||||
if (string.IsNullOrWhiteSpace(definitionStub.Name))
|
||||
definitionStub.Name = GenerateTypeName(definitionStub.DisplayName);
|
||||
|
||||
while (_contentDefinitionManager.GetTypeDefinition(definitionStub.Name) != null)
|
||||
definitionStub.Name = VersionTypeName(definitionStub.Name);
|
||||
|
||||
//just giving the new type some default parts for now
|
||||
_contentDefinitionManager.AlterTypeDefinition(
|
||||
definitionStub.Name,
|
||||
cfg => cfg.Named(definitionStub.Name, definitionStub.DisplayName)
|
||||
.WithPart("CommonAspect")
|
||||
//.WithPart("RoutableAspect") //need to go the new routable route
|
||||
.WithPart("BodyAspect"));
|
||||
|
||||
Services.Notifier.Information(T("Created content type: {0}", definitionStub.DisplayName));
|
||||
}
|
||||
|
||||
public void RemoveTypeDefinition(string name) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
//gratuitously stolen from the RoutableService
|
||||
private static string GenerateTypeName(string displayName) {
|
||||
if (string.IsNullOrWhiteSpace(displayName))
|
||||
return "";
|
||||
|
||||
var name = displayName;
|
||||
//todo: might need to be made more restrictive depending on how name is used (like as an XML node name, for instance)
|
||||
var dissallowed = new Regex(@"[/:?#\[\]@!$&'()*+,;=\s]+");
|
||||
|
||||
name = dissallowed.Replace(name, "-");
|
||||
name = name.Trim('-');
|
||||
|
||||
if (name.Length > 128)
|
||||
name = name.Substring(0, 128);
|
||||
|
||||
return name.ToLowerInvariant();
|
||||
}
|
||||
|
||||
private static string VersionTypeName(string name) {
|
||||
var version = 2;
|
||||
var nameParts = name.Split(new[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (nameParts.Length > 1 && int.TryParse(nameParts.Last(), out version)) {
|
||||
version = version > 0 ? ++version : 2;
|
||||
//this could unintentionally chomp something that looks like a version
|
||||
name = string.Join("-", nameParts.Take(nameParts.Length - 1));
|
||||
}
|
||||
|
||||
return string.Format("{0}-{1}", name, version);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
|
||||
namespace Orchard.Core.Contents.Services {
|
||||
public interface IContentDefinitionService : IDependency {
|
||||
IEnumerable<ContentTypeDefinition> GetTypeDefinitions();
|
||||
ContentTypeDefinition GetTypeDefinition(string name);
|
||||
void AddTypeDefinition(ContentTypeDefinitionStub contentTypeDefinition);
|
||||
void RemoveTypeDefinition(string name);
|
||||
}
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
using Orchard.Mvc.ViewModels;
|
||||
|
||||
namespace Orchard.Core.Contents.ViewModels {
|
||||
public class CreateTypeViewModel : BaseViewModel {
|
||||
public string DisplayName { get; set; }
|
||||
}
|
||||
}
|
@@ -4,7 +4,7 @@ using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.Mvc.ViewModels;
|
||||
|
||||
namespace Orchard.Core.Contents.ViewModels {
|
||||
public class ContentTypeListViewModel : BaseViewModel {
|
||||
public class ListContentTypesViewModel : BaseViewModel {
|
||||
public IEnumerable<ContentTypeDefinition> Types { get; set; }
|
||||
}
|
||||
}
|
@@ -4,7 +4,7 @@ using Orchard.ContentManagement;
|
||||
using Orchard.Mvc.ViewModels;
|
||||
|
||||
namespace Orchard.Core.Contents.ViewModels {
|
||||
public class ListContentViewModel : BaseViewModel {
|
||||
public class ListContentsViewModel : BaseViewModel {
|
||||
public string Id { get; set; }
|
||||
public int? Page { get; set; }
|
||||
public IList<Entry> Entries { get; set; }
|
@@ -1,5 +1,4 @@
|
||||
<%@ Page Language="C#" Inherits="Orchard.Mvc.ViewPage<ContentTypeListViewModel>" %>
|
||||
|
||||
<%@ Page Language="C#" Inherits="Orchard.Mvc.ViewPage<ListContentTypesViewModel>" %>
|
||||
<%@ Import Namespace="Orchard.Core.Contents.ViewModels" %>
|
||||
<% Html.AddTitleParts(T("Create Content").ToString()); %>
|
||||
<p>
|
||||
|
13
src/Orchard.Web/Core/Contents/Views/Admin/CreateType.ascx
Normal file
13
src/Orchard.Web/Core/Contents/Views/Admin/CreateType.ascx
Normal file
@@ -0,0 +1,13 @@
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<CreateTypeViewModel>" %>
|
||||
<%@ Import Namespace="Orchard.Core.Contents.ViewModels" %>
|
||||
<h1><%:Html.TitleForPage(T("New Content Type").ToString())%></h1><%
|
||||
using (Html.BeginFormAntiForgeryPost()) { %>
|
||||
<%:Html.ValidationSummary() %>
|
||||
<fieldset>
|
||||
<label for="DisplayName"><%:T("Display Name") %></label>
|
||||
<%:Html.TextBoxFor(m => m.DisplayName, new {@class = "textMedium", autofocus = "autofocus"}) %>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<button class="primaryAction" type="submit"><%:T("Create") %></button>
|
||||
</fieldset><%
|
||||
} %>
|
@@ -1,5 +1,4 @@
|
||||
<%@ Page Language="C#" Inherits="Orchard.Mvc.ViewPage<ListContentViewModel>" %>
|
||||
|
||||
<%@ Page Language="C#" Inherits="Orchard.Mvc.ViewPage<ListContentsViewModel>" %>
|
||||
<%@ Import Namespace="Orchard.Core.Contents.ViewModels" %>
|
||||
<% Html.AddTitleParts(T("Browse Contents").ToString()); %>
|
||||
<p>
|
||||
|
9
src/Orchard.Web/Core/Contents/Views/Admin/Types.ascx
Normal file
9
src/Orchard.Web/Core/Contents/Views/Admin/Types.ascx
Normal file
@@ -0,0 +1,9 @@
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<ListContentTypesViewModel>" %>
|
||||
<%@ Import Namespace="Orchard.Core.Contents.ViewModels" %>
|
||||
<h1><%:Html.TitleForPage(T("Content Types").ToString())%></h1>
|
||||
<div class="manage"><%: Html.ActionLink(T("Create new type").ToString(), "CreateType", null, new { @class = "button primaryAction" })%></div>
|
||||
<%=Html.UnorderedList(
|
||||
Model.Types,
|
||||
(t,i) => Html.DisplayFor(m => t).ToHtmlString(),
|
||||
"contentItems"
|
||||
) %>
|
@@ -1,24 +0,0 @@
|
||||
<%@ Page Language="C#" Inherits="Orchard.Mvc.ViewPage<ContentTypeListViewModel>" %>
|
||||
|
||||
<%@ Import Namespace="Orchard.Core.Contents.ViewModels" %>
|
||||
<% Html.AddTitleParts(T("Create Content").ToString()); %>
|
||||
<p>
|
||||
Create content</p>
|
||||
<table>
|
||||
<% foreach (var t in Model.Types) {%>
|
||||
<tr>
|
||||
<td>
|
||||
<%:t.Name %>
|
||||
</td>
|
||||
<td>
|
||||
<%:Html.ActionLink(T("List Items").ToString(), "List", "Admin", new RouteValueDictionary{{"Area","Contents"},{"Id",t.Name}}, new Dictionary<string, object>()) %>
|
||||
</td>
|
||||
<td>
|
||||
<%:Html.ActionLink(T("Create Item").ToString(), "Create", "Admin", new RouteValueDictionary{{"Area","Contents"},{"Id",t.Name}}, new Dictionary<string, object>()) %>
|
||||
</td>
|
||||
<td>
|
||||
<%:Html.ActionLink(T("Edit Type").ToString(), "ContentTypeList", "Admin", new RouteValueDictionary{{"Area","Orchard.MetaData"},{"Id",t.Name}}, new Dictionary<string, object>()) %>
|
||||
</td>
|
||||
</tr>
|
||||
<%} %>
|
||||
</table>
|
@@ -0,0 +1,14 @@
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<Orchard.ContentManagement.MetaData.Models.ContentTypeDefinition>" %>
|
||||
<div class="summary">
|
||||
<div class="properties">
|
||||
<h3><%:Model.DisplayName%></h3>
|
||||
<p><%:Model.Name %> - <%:Html.ActionLink("[new content]", "Create", new {area = "Contents", id = Model.Name}) %></p>
|
||||
</div>
|
||||
<div class="related">
|
||||
<%:Html.ActionLink(T("List Items").ToString(), "List", new {area = "Contents", id = Model.Name})%><%:T(" | ")%>
|
||||
<%:Html.ActionLink(T("[Edit]").ToString(), "EditType", new {area = "Contents", id = Model.Name})%><%:T(" | ") %>
|
||||
<% using (Html.BeginFormAntiForgeryPost(Url.Action("RemoveType", new {area = "Contents", id = Model.Name}), FormMethod.Post, new { @class = "inline link" })) { %>
|
||||
<button type="submit" class="linkButton" title="<%:T("Delete") %>"><%:T("[Delete]")%></button><%
|
||||
} %>
|
||||
</div>
|
||||
</div>
|
@@ -37,7 +37,7 @@ namespace Orchard.Core.Indexing.Lucene {
|
||||
_analyzer = CreateAnalyzer();
|
||||
|
||||
// TODO: (sebros) Find a common way to get where tenant's specific files should go. "Sites/Tenant" is hard coded in multiple places
|
||||
_basePath = Path.Combine("Sites", _shellSettings.Name, "Indexes");
|
||||
_basePath = _appDataFolder.Combine("Sites", _shellSettings.Name, "Indexes");
|
||||
|
||||
Logger = NullLogger.Instance;
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace Orchard.Core.Indexing.Lucene {
|
||||
}
|
||||
|
||||
protected virtual Directory GetDirectory(string indexName) {
|
||||
var directoryInfo = new DirectoryInfo(_appDataFolder.MapPath(Path.Combine(_basePath, indexName)));
|
||||
var directoryInfo = new DirectoryInfo(_appDataFolder.MapPath(_appDataFolder.Combine(_basePath, indexName)));
|
||||
return FSDirectory.Open(directoryInfo);
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace Orchard.Core.Indexing.Lucene {
|
||||
}
|
||||
|
||||
public bool Exists(string indexName) {
|
||||
return new DirectoryInfo(_appDataFolder.MapPath(Path.Combine(_basePath, indexName))).Exists;
|
||||
return new DirectoryInfo(_appDataFolder.MapPath(_appDataFolder.Combine(_basePath, indexName))).Exists;
|
||||
}
|
||||
|
||||
public bool IsEmpty(string indexName) {
|
||||
@@ -114,7 +114,7 @@ namespace Orchard.Core.Indexing.Lucene {
|
||||
}
|
||||
|
||||
public void DeleteIndex(string indexName) {
|
||||
new DirectoryInfo(Path.Combine(_appDataFolder.MapPath(Path.Combine(_basePath, indexName))))
|
||||
new DirectoryInfo(_appDataFolder.MapPath(_appDataFolder.Combine(_basePath, indexName)))
|
||||
.Delete(true);
|
||||
|
||||
var settingsFileName = GetSettingsFileName(indexName);
|
||||
@@ -197,7 +197,7 @@ namespace Orchard.Core.Indexing.Lucene {
|
||||
}
|
||||
|
||||
private string GetSettingsFileName(string indexName) {
|
||||
return Path.Combine(_appDataFolder.MapPath(_basePath), indexName + ".settings.xml");
|
||||
return _appDataFolder.MapPath(_appDataFolder.Combine(_basePath, indexName + ".settings.xml"));
|
||||
}
|
||||
|
||||
public DateTime GetLastIndexUtc(string indexName) {
|
||||
|
@@ -5,7 +5,6 @@ using Orchard.Localization;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.Localization.Services;
|
||||
using Orchard.Settings;
|
||||
|
||||
namespace Orchard.Core.Localization.Handlers {
|
||||
[UsedImplicitly]
|
||||
@@ -20,7 +19,7 @@ namespace Orchard.Core.Localization.Handlers {
|
||||
|
||||
Filters.Add(StorageFilter.For(localizedRepository));
|
||||
|
||||
OnActivated<Localized>(InitializePart);
|
||||
OnInitializing<Localized>(InitializePart);
|
||||
|
||||
OnLoaded<Localized>(LazyLoadHandlers);
|
||||
|
||||
@@ -34,7 +33,7 @@ namespace Orchard.Core.Localization.Handlers {
|
||||
localized.MasterContentItemField.Loader(ctx => _contentManager.Get(localized.Record.MasterContentItemId));
|
||||
}
|
||||
|
||||
void InitializePart(ActivatedContentContext context, Localized localized) {
|
||||
void InitializePart(InitializingContentContext context, Localized localized) {
|
||||
localized.CultureField.Setter(cultureRecord => {
|
||||
localized.Record.CultureId = cultureRecord.Id;
|
||||
return cultureRecord;
|
||||
|
@@ -7,9 +7,10 @@ namespace Orchard.Core.Navigation {
|
||||
public string MenuName { get { return "admin"; } }
|
||||
|
||||
public void GetNavigation(NavigationBuilder builder) {
|
||||
builder.Add(T("Site"), "12",
|
||||
//todo: - add new menu? and list menus? ...and remove hard-coded menu name here
|
||||
builder.Add(T("Navigation"), "8",
|
||||
menu => menu
|
||||
.Add(T("Manage Menu"), "6.0", item => item.Action("Index", "Admin", new { area = "Navigation" }).Permission(Permissions.ManageMainMenu)));
|
||||
.Add(T("Main Menu"), "6.0", item => item.Action("Index", "Admin", new { area = "Navigation" }).Permission(Permissions.ManageMainMenu)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -13,7 +13,7 @@ namespace Orchard.Core.Navigation.Handlers {
|
||||
Filters.Add(new ActivatingFilter<MenuPart>("menuitem"));
|
||||
Filters.Add(StorageFilter.For(menuPartRepository));
|
||||
|
||||
OnActivated<MenuPart>((ctx, x) => {
|
||||
OnInitializing<MenuPart>((ctx, x) => {
|
||||
x.OnMainMenu = false;
|
||||
x.MenuText = String.Empty;
|
||||
});
|
||||
|
@@ -2,6 +2,7 @@
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Core.Navigation.Models;
|
||||
using Orchard.Localization;
|
||||
using Orchard.UI.Navigation;
|
||||
using MenuItem=Orchard.Core.Navigation.Models.MenuItem;
|
||||
|
||||
@@ -36,11 +37,11 @@ namespace Orchard.Core.Navigation.Services {
|
||||
|
||||
if (part.Is<MenuItem>())
|
||||
builder.Add(
|
||||
menu => menu.Add(part.MenuText, part.MenuPosition, nib => nib.Url(part.As<MenuItem>().Url)));
|
||||
menu => menu.Add(new LocalizedString(part.MenuText), part.MenuPosition, nib => nib.Url(part.As<MenuItem>().Url)));
|
||||
else
|
||||
builder.Add(
|
||||
menu =>
|
||||
menu.Add(part.MenuText, part.MenuPosition,
|
||||
menu.Add(new LocalizedString(part.MenuText), part.MenuPosition,
|
||||
nib =>
|
||||
nib.Action(_contentManager.GetItemMetadata(part.ContentItem).DisplayRouteValues)));
|
||||
}
|
||||
|
@@ -69,10 +69,22 @@
|
||||
<Compile Include="Common\Drivers\CommonDriver.cs" />
|
||||
<Compile Include="Common\Drivers\RoutableDriver.cs" />
|
||||
<Compile Include="Common\Controllers\RoutableController.cs" />
|
||||
<Compile Include="Common\Drivers\TextContentFieldDriver.cs" />
|
||||
<Compile Include="Common\Fields\TextContentField.cs" />
|
||||
<Compile Include="Common\Handlers\RoutableAspectHandler.cs" />
|
||||
<Compile Include="Common\Handlers\TextContentFieldHandler.cs" />
|
||||
<Compile Include="Common\ViewModels\ContainerEditorViewModel.cs" />
|
||||
<Compile Include="Common\ViewModels\TextContentFieldDisplayViewModel.cs" />
|
||||
<Compile Include="Common\ViewModels\TextContentFieldEditorViewModel.cs" />
|
||||
<Compile Include="Contents\ContentTypeDefinitionStub.cs" />
|
||||
<Compile Include="Contents\Controllers\ItemController.cs" />
|
||||
<Compile Include="Contents\Handlers\ContentsModuleHandler.cs" />
|
||||
<Compile Include="Contents\Permissions.cs" />
|
||||
<Compile Include="Contents\Services\ContentDefinitionService.cs" />
|
||||
<Compile Include="Contents\Services\IContentDefinitionService.cs" />
|
||||
<Compile Include="Contents\ViewModels\CreateTypeViewModel.cs" />
|
||||
<Compile Include="Contents\ViewModels\ListContentsViewModel.cs" />
|
||||
<Compile Include="Contents\ViewModels\ListContentTypesViewModel.cs" />
|
||||
<Compile Include="Localization\Drivers\LocalizedDriver.cs" />
|
||||
<Compile Include="Routable\Controllers\ItemController.cs" />
|
||||
<Compile Include="Routable\Drivers\RoutableDriver.cs" />
|
||||
@@ -100,9 +112,7 @@
|
||||
<Compile Include="Contents\AdminMenu.cs" />
|
||||
<Compile Include="Contents\Controllers\AdminController.cs" />
|
||||
<Compile Include="Contents\ViewModels\CreateItemViewModel.cs" />
|
||||
<Compile Include="Contents\ViewModels\ContentTypeListViewModel.cs" />
|
||||
<Compile Include="Contents\ViewModels\EditItemViewModel.cs" />
|
||||
<Compile Include="Contents\ViewModels\ListContentViewModel.cs" />
|
||||
<Compile Include="Dashboard\AdminMenu.cs" />
|
||||
<Compile Include="Dashboard\Controllers\AdminController.cs" />
|
||||
<Compile Include="Dashboard\Routes.cs" />
|
||||
@@ -182,10 +192,10 @@
|
||||
<Compile Include="Settings\State\Records\ShellFeatureStateRecord.cs" />
|
||||
<Compile Include="Settings\State\Records\ShellStateRecord.cs" />
|
||||
<Compile Include="Settings\State\ShellStateManager.cs" />
|
||||
<Compile Include="Settings\Topology\Records\ShellFeatureRecord.cs" />
|
||||
<Compile Include="Settings\Topology\Records\ShellParameterRecord.cs" />
|
||||
<Compile Include="Settings\Topology\Records\ShellDescriptorRecord.cs" />
|
||||
<Compile Include="Settings\Topology\ShellDescriptorManager.cs" />
|
||||
<Compile Include="Settings\Descriptor\Records\ShellFeatureRecord.cs" />
|
||||
<Compile Include="Settings\Descriptor\Records\ShellParameterRecord.cs" />
|
||||
<Compile Include="Settings\Descriptor\Records\ShellDescriptorRecord.cs" />
|
||||
<Compile Include="Settings\Descriptor\ShellDescriptorManager.cs" />
|
||||
<Compile Include="Settings\AdminMenu.cs" />
|
||||
<Compile Include="Settings\Controllers\AdminController.cs" />
|
||||
<Compile Include="Settings\Handlers\SiteSettingsHandler.cs" />
|
||||
@@ -207,13 +217,17 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Common\Module.txt" />
|
||||
<Content Include="Common\Views\DisplayTemplates\Fields\Common.TextContentField.ascx" />
|
||||
<Content Include="Common\Views\EditorTemplates\Parts\Common.Container.ascx" />
|
||||
<Content Include="Common\Views\EditorTemplates\Parts\Common.TextContentField.ascx" />
|
||||
<Content Include="Contents\Module.txt" />
|
||||
<Content Include="Contents\Views\Admin\Types.aspx" />
|
||||
<Content Include="Contents\Views\Admin\CreateType.ascx" />
|
||||
<Content Include="Contents\Views\Admin\Types.ascx" />
|
||||
<Content Include="Contents\Views\Admin\List.aspx" />
|
||||
<Content Include="Contents\Views\Admin\Edit.aspx" />
|
||||
<Content Include="Contents\Views\Admin\CreatableTypeList.aspx" />
|
||||
<Content Include="Contents\Views\Admin\Create.aspx" />
|
||||
<Content Include="Contents\Views\DisplayTemplates\ContentTypeDefinition.ascx" />
|
||||
<Content Include="Contents\Views\DisplayTemplates\Items\Contents.Item.ascx" />
|
||||
<Content Include="Contents\Views\EditorTemplates\Items\Contents.Item.ascx" />
|
||||
<Content Include="Contents\Views\Item\Preview.aspx" />
|
||||
|
@@ -83,7 +83,7 @@ namespace Orchard.Core.Routable.Drivers {
|
||||
}
|
||||
|
||||
if (!_routableService.IsSlugValid(part.Slug)) {
|
||||
updater.AddModelError("Routable.Slug", T("Please do not use any of the following characters in your slugs: \"/\", \":\", \"?\", \"#\", \"[\", \"]\", \"@\", \"!\", \"$\", \"&\", \"'\", \"(\", \")\", \"*\", \"+\", \",\", \";\", \"=\". No spaces are allowed (please use dashes or underscores instead).").ToString());
|
||||
updater.AddModelError("Routable.Slug", T("Please do not use any of the following characters in your slugs: \"/\", \":\", \"?\", \"#\", \"[\", \"]\", \"@\", \"!\", \"$\", \"&\", \"'\", \"(\", \")\", \"*\", \"+\", \",\", \";\", \"=\". No spaces are allowed (please use dashes or underscores instead)."));
|
||||
}
|
||||
|
||||
string originalSlug = part.Slug;
|
||||
|
@@ -7,9 +7,9 @@ namespace Orchard.Core.Settings {
|
||||
public string MenuName { get { return "admin"; } }
|
||||
|
||||
public void GetNavigation(NavigationBuilder builder) {
|
||||
builder.Add(T("Site"), "11",
|
||||
builder.Add(T("Site Configuration"), "11",
|
||||
menu => menu
|
||||
.Add(T("Manage Settings"), "2.0", item => item.Action("Index", "Admin", new { area = "Settings" }).Permission(Permissions.ManageSettings)));
|
||||
.Add(T("Settings"), "2.0", item => item.Action("Index", "Admin", new { area = "Settings" }).Permission(Permissions.ManageSettings)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Data.Conventions;
|
||||
|
||||
namespace Orchard.Core.Settings.Topology.Records {
|
||||
namespace Orchard.Core.Settings.Descriptor.Records {
|
||||
public class ShellDescriptorRecord {
|
||||
public ShellDescriptorRecord() {
|
||||
Features=new List<ShellFeatureRecord>();
|
@@ -1,4 +1,4 @@
|
||||
namespace Orchard.Core.Settings.Topology.Records {
|
||||
namespace Orchard.Core.Settings.Descriptor.Records {
|
||||
public class ShellFeatureRecord {
|
||||
public virtual int Id { get; set; }
|
||||
public virtual ShellDescriptorRecord ShellDescriptorRecord { get; set; }
|
@@ -1,4 +1,4 @@
|
||||
namespace Orchard.Core.Settings.Topology.Records {
|
||||
namespace Orchard.Core.Settings.Descriptor.Records {
|
||||
public class ShellParameterRecord {
|
||||
public virtual int Id { get; set; }
|
||||
public virtual ShellDescriptorRecord ShellDescriptorRecord { get; set; }
|
@@ -1,12 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Core.Settings.Topology.Records;
|
||||
using Orchard.Core.Settings.Descriptor.Records;
|
||||
using Orchard.Data;
|
||||
using Orchard.Environment.Topology;
|
||||
using Orchard.Environment.Topology.Models;
|
||||
using Orchard.Environment.Descriptor;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.Localization;
|
||||
|
||||
namespace Orchard.Core.Settings.Topology {
|
||||
namespace Orchard.Core.Settings.Descriptor {
|
||||
public class ShellDescriptorManager : IShellDescriptorManager {
|
||||
private readonly IRepository<ShellDescriptorRecord> _shellDescriptorRepository;
|
||||
private readonly IShellDescriptorManagerEventHandler _events;
|
||||
@@ -22,25 +22,25 @@ namespace Orchard.Core.Settings.Topology {
|
||||
Localizer T { get; set; }
|
||||
|
||||
public ShellDescriptor GetShellDescriptor() {
|
||||
ShellDescriptorRecord shellDescriptorRecord = GetTopologyRecord();
|
||||
ShellDescriptorRecord shellDescriptorRecord = GetDescriptorRecord();
|
||||
if (shellDescriptorRecord == null) return null;
|
||||
return GetShellTopologyDescriptorFromRecord(shellDescriptorRecord);
|
||||
return GetShellDescriptorFromRecord(shellDescriptorRecord);
|
||||
}
|
||||
|
||||
private static ShellDescriptor GetShellTopologyDescriptorFromRecord(ShellDescriptorRecord shellDescriptorRecord) {
|
||||
private static ShellDescriptor GetShellDescriptorFromRecord(ShellDescriptorRecord shellDescriptorRecord) {
|
||||
ShellDescriptor descriptor = new ShellDescriptor { SerialNumber = shellDescriptorRecord.SerialNumber };
|
||||
var descriptorFeatures = new List<ShellFeature>();
|
||||
foreach (var topologyFeatureRecord in shellDescriptorRecord.Features) {
|
||||
descriptorFeatures.Add(new ShellFeature { Name = topologyFeatureRecord.Name });
|
||||
foreach (var descriptorFeatureRecord in shellDescriptorRecord.Features) {
|
||||
descriptorFeatures.Add(new ShellFeature { Name = descriptorFeatureRecord.Name });
|
||||
}
|
||||
descriptor.Features = descriptorFeatures;
|
||||
var descriptorParameters = new List<ShellParameter>();
|
||||
foreach (var topologyParameterRecord in shellDescriptorRecord.Parameters) {
|
||||
foreach (var descriptorParameterRecord in shellDescriptorRecord.Parameters) {
|
||||
descriptorParameters.Add(
|
||||
new ShellParameter {
|
||||
Component = topologyParameterRecord.Component,
|
||||
Name = topologyParameterRecord.Name,
|
||||
Value = topologyParameterRecord.Value
|
||||
Component = descriptorParameterRecord.Component,
|
||||
Name = descriptorParameterRecord.Name,
|
||||
Value = descriptorParameterRecord.Value
|
||||
});
|
||||
}
|
||||
descriptor.Parameters = descriptorParameters;
|
||||
@@ -48,15 +48,15 @@ namespace Orchard.Core.Settings.Topology {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
private ShellDescriptorRecord GetTopologyRecord() {
|
||||
private ShellDescriptorRecord GetDescriptorRecord() {
|
||||
return _shellDescriptorRepository.Get(x => true);
|
||||
}
|
||||
|
||||
public void UpdateShellDescriptor(int priorSerialNumber, IEnumerable<ShellFeature> enabledFeatures, IEnumerable<ShellParameter> parameters) {
|
||||
ShellDescriptorRecord shellDescriptorRecord = GetTopologyRecord();
|
||||
ShellDescriptorRecord shellDescriptorRecord = GetDescriptorRecord();
|
||||
var serialNumber = shellDescriptorRecord == null ? 0 : shellDescriptorRecord.SerialNumber;
|
||||
if (priorSerialNumber != serialNumber)
|
||||
throw new InvalidOperationException(T("Invalid serial number for shell topology").ToString());
|
||||
throw new InvalidOperationException(T("Invalid serial number for shell descriptor").ToString());
|
||||
|
||||
if (shellDescriptorRecord == null) {
|
||||
shellDescriptorRecord = new ShellDescriptorRecord { SerialNumber = 1 };
|
||||
@@ -82,7 +82,7 @@ namespace Orchard.Core.Settings.Topology {
|
||||
});
|
||||
}
|
||||
|
||||
_events.Changed(GetShellTopologyDescriptorFromRecord(shellDescriptorRecord));
|
||||
_events.Changed(GetShellDescriptorFromRecord(shellDescriptorRecord));
|
||||
}
|
||||
|
||||
|
@@ -54,7 +54,7 @@ namespace Orchard.Core.Settings.Metadata {
|
||||
private ContentTypeDefinitionRecord Acquire(ContentTypeDefinition contentTypeDefinition) {
|
||||
var result = _typeDefinitionRepository.Fetch(x => x.Name == contentTypeDefinition.Name).SingleOrDefault();
|
||||
if (result == null) {
|
||||
result = new ContentTypeDefinitionRecord { Name = contentTypeDefinition.Name };
|
||||
result = new ContentTypeDefinitionRecord { Name = contentTypeDefinition.Name, DisplayName = contentTypeDefinition.DisplayName};
|
||||
_typeDefinitionRepository.Create(result);
|
||||
}
|
||||
return result;
|
||||
@@ -100,6 +100,7 @@ namespace Orchard.Core.Settings.Metadata {
|
||||
ContentTypeDefinition Build(ContentTypeDefinitionRecord source) {
|
||||
return new ContentTypeDefinition(
|
||||
source.Name,
|
||||
source.DisplayName,
|
||||
source.ContentTypePartDefinitionRecords.Select(Build),
|
||||
_settingsReader.Map(Parse(source.Settings)));
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@ namespace Orchard.Core.Settings.Metadata.Records {
|
||||
|
||||
public virtual int Id { get; set; }
|
||||
public virtual string Name { get; set; }
|
||||
public virtual string DisplayName { get; set; }
|
||||
public virtual bool Hidden { get; set; }
|
||||
public virtual string Settings { get; set; }
|
||||
|
||||
|
@@ -3,7 +3,7 @@ using Orchard.Core.Settings.State.Records;
|
||||
using Orchard.Data;
|
||||
using Orchard.Environment.State;
|
||||
using Orchard.Environment.State.Models;
|
||||
using Orchard.Environment.Topology;
|
||||
using Orchard.Environment.Descriptor;
|
||||
using Orchard.Logging;
|
||||
|
||||
namespace Orchard.Core.Settings.State {
|
||||
|
@@ -3,13 +3,12 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using Autofac;
|
||||
using Autofac.Builder;
|
||||
using Autofac.Integration.Web;
|
||||
using Autofac.Integration.Web.Mvc;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Environment.Extensions.Loaders;
|
||||
|
||||
namespace Orchard.Web {
|
||||
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
|
||||
@@ -101,6 +100,5 @@ namespace Orchard.Web {
|
||||
builder.RegisterInstance(ModelMetadataProviders.Current);
|
||||
builder.RegisterInstance(ViewEngines.Engines);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@ namespace Orchard.Blogs {
|
||||
public string MenuName { get { return "admin"; } }
|
||||
|
||||
public void GetNavigation(NavigationBuilder builder) {
|
||||
builder.Add(T("Blogs"), "2", BuildMenu);
|
||||
builder.Add(T("Blogs"), "1", BuildMenu);
|
||||
}
|
||||
|
||||
private void BuildMenu(NavigationItemBuilder menu) {
|
||||
@@ -33,12 +33,12 @@ namespace Orchard.Blogs {
|
||||
item =>
|
||||
item.Action("Item", "BlogAdmin", new {area = "Orchard.Blogs", blogSlug = singleBlog.Slug}).Permission(Permissions.MetaListBlogs));
|
||||
|
||||
menu.Add(T("Add New Blog"), "1.1",
|
||||
menu.Add(T("Create New Blog"), "1.1",
|
||||
item =>
|
||||
item.Action("Create", "BlogAdmin", new {area = "Orchard.Blogs"}).Permission(Permissions.ManageBlogs));
|
||||
|
||||
if (singleBlog != null)
|
||||
menu.Add(T("Add New Post"), "1.2",
|
||||
menu.Add(T("Create New Post"), "1.2",
|
||||
item =>
|
||||
item.Action("Create", "BlogPostAdmin", new {area = "Orchard.Blogs", blogSlug = singleBlog.Slug}).Permission(Permissions.PublishBlogPost));
|
||||
}
|
||||
|
@@ -40,6 +40,9 @@ namespace Orchard.Blogs.Drivers {
|
||||
}
|
||||
|
||||
public override RouteValueDictionary GetDisplayRouteValues(BlogPost post) {
|
||||
if (post.Blog == null)
|
||||
return new RouteValueDictionary();
|
||||
|
||||
return new RouteValueDictionary {
|
||||
{"Area", "Orchard.Blogs"},
|
||||
{"Controller", "BlogPost"},
|
||||
@@ -50,6 +53,9 @@ namespace Orchard.Blogs.Drivers {
|
||||
}
|
||||
|
||||
public override RouteValueDictionary GetEditorRouteValues(BlogPost post) {
|
||||
if (post.Blog == null)
|
||||
return new RouteValueDictionary();
|
||||
|
||||
return new RouteValueDictionary {
|
||||
{"Area", "Orchard.Blogs"},
|
||||
{"Controller", "BlogPostAdmin"},
|
||||
@@ -59,6 +65,18 @@ namespace Orchard.Blogs.Drivers {
|
||||
};
|
||||
}
|
||||
|
||||
public override RouteValueDictionary GetCreateRouteValues(BlogPost post) {
|
||||
if (post.Blog == null)
|
||||
return new RouteValueDictionary();
|
||||
|
||||
return new RouteValueDictionary {
|
||||
{"Area", "Orchard.Blogs"},
|
||||
{"Controller", "BlogPostAdmin"},
|
||||
{"Action", "Create"},
|
||||
{"blogSlug", post.Blog.Slug},
|
||||
};
|
||||
}
|
||||
|
||||
protected override DriverResult Display(BlogPost post, string displayType) {
|
||||
return Combined(
|
||||
ContentItemTemplate("Items/Blogs.BlogPost").LongestMatch(displayType, "Summary", "SummaryAdmin"),
|
||||
|
@@ -8,9 +8,7 @@ using Orchard.Blogs.Services;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.Core.Common.Services;
|
||||
using Orchard.Localization;
|
||||
using Orchard.UI.Notify;
|
||||
|
||||
namespace Orchard.Blogs.Handlers {
|
||||
[UsedImplicitly]
|
||||
@@ -40,7 +38,7 @@ namespace Orchard.Blogs.Handlers {
|
||||
blog.PostCount = posts.Count;
|
||||
});
|
||||
|
||||
OnActivated<BlogPost>((context, bp) => {
|
||||
OnInitializing<BlogPost>((context, bp) => {
|
||||
var blogSlug = requestContext.RouteData.Values.ContainsKey("blogSlug") ? requestContext.RouteData.Values["blogSlug"] as string : null;
|
||||
if (!string.IsNullOrEmpty(blogSlug)) {
|
||||
bp.Blog = blogService.Get(blogSlug);
|
||||
|
@@ -27,7 +27,7 @@
|
||||
<li><%
|
||||
if (Model.Item.ScheduledPublishUtc.HasValue && Model.Item.ScheduledPublishUtc.Value > DateTime.UtcNow) { %>
|
||||
<img class="icon" src="<%=ResolveUrl("~/Modules/Orchard.Blogs/Content/Admin/images/scheduled.gif") %>" alt="<%: T("Scheduled") %>" title="<%: T("The post is scheduled for publishing") %>" /><%: T("Scheduled")%>
|
||||
<%=Html.DateTime(Model.Item.ScheduledPublishUtc.Value, "M/d/yyyy h:mm tt")%><%
|
||||
<%=Html.DateTime(Model.Item.ScheduledPublishUtc.Value, T("M/d/yyyy h:mm tt"))%><%
|
||||
}
|
||||
else if (Model.Item.IsPublished) { %>
|
||||
<%: T("Published: {0}", Html.DateTimeRelative(Model.Item.As<ICommonAspect>().VersionPublishedUtc.Value, T)) %><%
|
||||
|
@@ -48,7 +48,7 @@ namespace Orchard.Comments.Controllers {
|
||||
|
||||
if(!TryUpdateModel(viewModel)) {
|
||||
if (Request.Form["Name"].IsNullOrEmptyTrimmed()) {
|
||||
_notifier.Error("You must provide a Name in order to comment");
|
||||
_notifier.Error(T("You must provide a Name in order to comment"));
|
||||
}
|
||||
return Redirect(returnUrl);
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@ namespace Orchard.Comments.Handlers {
|
||||
|
||||
Filters.Add(StorageFilter.For(hasCommentsRepository));
|
||||
|
||||
OnActivated<HasComments>((ctx, x) => {
|
||||
OnInitializing<HasComments>((ctx, x) => {
|
||||
x.CommentsActive = true;
|
||||
x.CommentsShown = true;
|
||||
});
|
||||
|
@@ -22,7 +22,7 @@ namespace Orchard.DevTools.Controllers {
|
||||
}
|
||||
|
||||
public ActionResult NotAuthorized() {
|
||||
_notifier.Warning("Simulated error goes here.");
|
||||
_notifier.Warning(T("Simulated error goes here."));
|
||||
return new HttpUnauthorizedResult();
|
||||
}
|
||||
|
||||
|
@@ -2,7 +2,6 @@
|
||||
<%@ Import Namespace="Orchard.Mvc.ViewModels"%>
|
||||
<h1><%: Html.TitleForPage(T("Dev Tools").ToString()) %></h1>
|
||||
<p><%: Html.ActionLink(T("Contents").ToString(), "Index", "Content") %></p>
|
||||
|
||||
<p><%: Html.ActionLink(T("Metadata").ToString(), "Index", "Metadata") %></p>
|
||||
<p><%: Html.ActionLink(T("Test Unauthorized Request").ToString(), "NotAuthorized", "Home")%></p>
|
||||
|
||||
|
@@ -42,7 +42,7 @@ namespace Orchard.Media.Controllers {
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
catch (Exception exception) {
|
||||
Services.Notifier.Error("Deleting Folder failed: " + exception.Message);
|
||||
Services.Notifier.Error(T("Deleting Folder failed: {0}", exception.Message));
|
||||
return View();
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ namespace Orchard.Media.Controllers {
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
catch (Exception exception) {
|
||||
Services.Notifier.Error("Creating Folder failed: " + exception.Message);
|
||||
Services.Notifier.Error(T("Creating Folder failed: {0}", exception.Message));
|
||||
return View(viewModel);
|
||||
}
|
||||
}
|
||||
@@ -96,7 +96,7 @@ namespace Orchard.Media.Controllers {
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
catch (Exception exception) {
|
||||
Services.Notifier.Error("Deleting failed: " + exception.Message);
|
||||
Services.Notifier.Error(T("Deleting failed: {0}", exception.Message));
|
||||
return View();
|
||||
}
|
||||
}
|
||||
@@ -128,7 +128,7 @@ namespace Orchard.Media.Controllers {
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
catch (Exception exception) {
|
||||
Services.Notifier.Error("Modifying Folder Properties failed: " + exception.Message);
|
||||
Services.Notifier.Error(T("Modifying Folder Properties failed: {0}", exception.Message));
|
||||
return View(viewModel);
|
||||
}
|
||||
}
|
||||
@@ -161,7 +161,7 @@ namespace Orchard.Media.Controllers {
|
||||
return RedirectToAction("Edit", new { name = viewModel.FolderName, mediaPath = viewModel.MediaPath });
|
||||
}
|
||||
catch (Exception exception) {
|
||||
Services.Notifier.Error("Uploading media file failed: " + exception.Message);
|
||||
Services.Notifier.Error(T("Uploading media file failed: {0}", exception.Message));
|
||||
return View(viewModel);
|
||||
}
|
||||
}
|
||||
@@ -240,7 +240,7 @@ namespace Orchard.Media.Controllers {
|
||||
mediaPath = viewModel.MediaPath });
|
||||
}
|
||||
catch (Exception exception) {
|
||||
Services.Notifier.Error("Editing media file failed: " + exception.Message);
|
||||
Services.Notifier.Error(T("Editing media file failed: {0}", exception.Message));
|
||||
return View(viewModel);
|
||||
}
|
||||
}
|
||||
|
@@ -9,10 +9,10 @@ namespace Orchard.Media.Handlers {
|
||||
public MediaSettingsHandler(IRepository<MediaSettingsRecord> repository) {
|
||||
Filters.Add(new ActivatingFilter<MediaSettings>("site"));
|
||||
Filters.Add(StorageFilter.For(repository) );
|
||||
OnActivated<MediaSettings>(DefaultSettings);
|
||||
OnInitializing<MediaSettings>(DefaultSettings);
|
||||
}
|
||||
|
||||
private static void DefaultSettings(ActivatedContentContext context, MediaSettings settings) {
|
||||
private static void DefaultSettings(InitializingContentContext context, MediaSettings settings) {
|
||||
settings.Record.RootMediaFolder = "~/Media";
|
||||
}
|
||||
}
|
||||
|
@@ -10,9 +10,9 @@ namespace Orchard.MetaData {
|
||||
|
||||
public void GetNavigation(NavigationBuilder builder)
|
||||
{
|
||||
builder.Add(T("Content Types"), "5",
|
||||
builder.Add(T("Site Configuration"), "11",
|
||||
menu => menu
|
||||
.Add(T("Content Types"), "1.0", item => item.Action("ContentTypeList", "Admin", new { area = "Orchard.MetaData" }).Permission(Permissions.ManageMetaData))
|
||||
.Add(T("Content Types (metadata)"), "3.1", item => item.Action("ContentTypeList", "Admin", new { area = "Orchard.MetaData" }).Permission(Permissions.ManageMetaData))
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -25,7 +25,7 @@
|
||||
%>
|
||||
<tr class="<%=contentTypeClass %>">
|
||||
<td>
|
||||
<%= Html.ActionLink(item.Name, "ContentTypeList", new {id=item.Name})%>
|
||||
<%= Html.ActionLink(string.IsNullOrWhiteSpace(item.Name) ? "unkwn" : item.Name, "ContentTypeList", new {id=item.Name})%>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
@@ -8,11 +8,11 @@ namespace Orchard.Modules {
|
||||
public string MenuName { get { return "admin"; } }
|
||||
|
||||
public void GetNavigation(NavigationBuilder builder) {
|
||||
builder.Add(T("Features"), "10",
|
||||
builder.Add(T("Site Configuration"), "11",
|
||||
menu => menu
|
||||
.Add(T("Manage Features"), "1.0", item => item.Action("Features", "Admin", new { area = "Orchard.Modules" })
|
||||
.Add(T("Features"), "5.0", item => item.Action("Features", "Admin", new { area = "Orchard.Modules" })
|
||||
.Permission(Permissions.ManageFeatures))
|
||||
.Add(T("Installed Modules"), "2.0", item => item.Action("Index", "Admin", new { area = "Orchard.Modules" })
|
||||
.Add(T("Modules"), "5.1", item => item.Action("Index", "Admin", new { area = "Orchard.Modules" })
|
||||
.Permission(Permissions.ManageModules)));
|
||||
}
|
||||
}
|
||||
|
@@ -4,8 +4,8 @@ using System.Linq;
|
||||
using System.Web;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.Environment.Topology;
|
||||
using Orchard.Environment.Topology.Models;
|
||||
using Orchard.Environment.Descriptor;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Modules.Models;
|
||||
using Orchard.UI.Notify;
|
||||
|
@@ -1,4 +1,5 @@
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<FeaturesViewModel>" %>
|
||||
<%@ Import Namespace="Orchard.Localization" %>
|
||||
<%@ Import Namespace="Orchard.Modules.Extensions" %>
|
||||
<%@ Import Namespace="Orchard.Mvc.Html"%>
|
||||
<%@ Import Namespace="Orchard.Modules.ViewModels"%>
|
||||
@@ -11,7 +12,7 @@
|
||||
<ul class="features summary-view switchable"><%
|
||||
var featureGroups = Model.Features.OrderBy(f => f.Descriptor.Category).GroupBy(f => f.Descriptor.Category);
|
||||
foreach (var featureGroup in featureGroups) {
|
||||
var categoryName = featureGroup.First().Descriptor.Category ?? T("Uncategorized");
|
||||
var categoryName = LocalizedString.TextOrDefault(featureGroup.First().Descriptor.Category, T("Uncategorized"));
|
||||
var categoryClassName = string.Format("category {0}", Html.Encode(categoryName.ToString().HtmlClassify()));
|
||||
if (featureGroup == featureGroups.First())
|
||||
categoryClassName += " first";
|
||||
|
@@ -55,7 +55,7 @@ namespace Orchard.MultiTenancy.Controllers {
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
catch (Exception exception) {
|
||||
Services.Notifier.Error(T("Creating Tenant failed: ") + exception.Message);
|
||||
Services.Notifier.Error(T("Creating Tenant failed: {0}", exception.Message));
|
||||
return View(viewModel);
|
||||
}
|
||||
}
|
||||
@@ -103,7 +103,7 @@ namespace Orchard.MultiTenancy.Controllers {
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
catch (Exception exception) {
|
||||
Services.Notifier.Error(T("Failed to edit tenant: ") + exception.Message);
|
||||
Services.Notifier.Error(T("Failed to edit tenant: {0} ", exception.Message));
|
||||
return View(viewModel);
|
||||
}
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@ namespace Orchard.Pages {
|
||||
item =>
|
||||
item.Action("List", "Admin", new {area = "Orchard.Pages"}).Permission(Permissions.MetaListPages));
|
||||
|
||||
menu.Add(T("Add New Page"), "1.1",
|
||||
menu.Add(T("Create New Page"), "1.1",
|
||||
item =>
|
||||
item.Action("Create", "Admin", new {area = "Orchard.Pages"}).Permission(Permissions.EditPages));
|
||||
}
|
||||
|
@@ -61,6 +61,14 @@ namespace Orchard.Pages.Drivers {
|
||||
};
|
||||
}
|
||||
|
||||
public override RouteValueDictionary GetCreateRouteValues(Page page) {
|
||||
return new RouteValueDictionary {
|
||||
{"Area", "Orchard.Pages"},
|
||||
{"Controller", "Admin"},
|
||||
{"Action", "Create"},
|
||||
};
|
||||
}
|
||||
|
||||
protected override DriverResult Display(Page page, string displayType) {
|
||||
return Combined(
|
||||
ContentItemTemplate("Items/Pages.Page").LongestMatch(displayType, "Summary", "SummaryAdmin"),
|
||||
|
@@ -62,7 +62,7 @@ using (Html.BeginFormAntiForgeryPost()) { %>
|
||||
<li><%
|
||||
if (pageEntry.Page.ScheduledPublishUtc.HasValue && pageEntry.Page.ScheduledPublishUtc.Value > DateTime.UtcNow) { %>
|
||||
<img class="icon" src="<%=ResolveUrl("~/Modules/Orchard.Pages/Content/Admin/images/scheduled.gif") %>" alt="<%: T("Scheduled") %>" title="<%: T("The page is scheduled for publishing") %>" /><%: T("Scheduled")%>
|
||||
<%=Html.DateTime(pageEntry.Page.ScheduledPublishUtc.Value, "M/d/yyyy h:mm tt")%><%
|
||||
<%=Html.DateTime(pageEntry.Page.ScheduledPublishUtc.Value, T("M/d/yyyy h:mm tt"))%><%
|
||||
}
|
||||
else if (pageEntry.Page.IsPublished) { %>
|
||||
<%: T("Published: {0}", Html.DateTimeRelative(pageEntry.Page.As<ICommonAspect>().VersionPublishedUtc.Value, T)) %><%
|
||||
|
@@ -1,9 +1,7 @@
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<ContentItemViewModel<Orchard.Pages.Models.Page>>" %>
|
||||
<%@ Import Namespace="Orchard.Mvc.Html"%>
|
||||
<%@ Import Namespace="Orchard.ContentManagement"%>
|
||||
<%@ Import Namespace="Orchard.Core.Common.Models"%>
|
||||
<%@ Import Namespace="Orchard.Mvc.ViewModels"%>
|
||||
<h3><a href="<%=Url.Action(T("Item").ToString(), "Page", new { area = "Orchard.Pages", slug = Model.Item.Slug }) %>"><%: Model.Item.Title %></a></h3>
|
||||
<h3><a href="<%:Url.Action("Item", "Page", new { area = "Orchard.Pages", slug = Model.Item.Slug }) %>"><%: Model.Item.Title %></a></h3>
|
||||
<div class="content">
|
||||
<% Html.Zone("primary", ":manage :metadata"); %>
|
||||
</div>
|
@@ -7,10 +7,9 @@ namespace Orchard.Roles {
|
||||
public string MenuName { get { return "admin"; } }
|
||||
|
||||
public void GetNavigation(NavigationBuilder builder) {
|
||||
builder.Add(T("Users"), "5",
|
||||
builder.Add(T("Users"), "9",
|
||||
menu => menu
|
||||
.Add(T("Manage Roles"), "2.0", item => item.Action("Index", "Admin", new { area = "Orchard.Roles" }).Permission(Permissions.ManageRoles))
|
||||
.Add(T("Add New Role"), "2.1", item => item.Action("Create", "Admin", new { area = "Orchard.Roles" }).Permission(Permissions.ManageRoles)));
|
||||
.Add(T("Manage Roles"), "2.0", item => item.Action("Index", "Admin", new { area = "Orchard.Roles" }).Permission(Permissions.ManageRoles)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@ namespace Orchard.Roles.Controllers {
|
||||
Services = services;
|
||||
_roleService = roleService;
|
||||
_authorizationService = authorizationService;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public IOrchardServices Services { get; set; }
|
||||
@@ -55,7 +56,7 @@ namespace Orchard.Roles.Controllers {
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
catch (Exception exception) {
|
||||
Services.Notifier.Error("Deleting Role failed: " + exception.Message);
|
||||
Services.Notifier.Error(T("Deleting Role failed: {0}", exception.Message));
|
||||
return View();
|
||||
}
|
||||
}
|
||||
@@ -87,7 +88,7 @@ namespace Orchard.Roles.Controllers {
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
catch (Exception exception) {
|
||||
Services.Notifier.Error("Creating Role failed: " + exception.Message);
|
||||
Services.Notifier.Error(T("Creating Role failed: {0}", exception.Message));
|
||||
return RedirectToAction("Create");
|
||||
}
|
||||
}
|
||||
@@ -141,7 +142,7 @@ namespace Orchard.Roles.Controllers {
|
||||
return RedirectToAction("Edit", new { viewModel.Id });
|
||||
}
|
||||
catch (Exception exception) {
|
||||
Services.Notifier.Error("Editing Role failed: " + exception.Message);
|
||||
Services.Notifier.Error(T("Editing Role failed: {0}", exception.Message));
|
||||
return RedirectToAction("Edit", viewModel.Id);
|
||||
}
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@ using JetBrains.Annotations;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.Data;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Roles.Models;
|
||||
using Orchard.Roles.Services;
|
||||
using Orchard.Roles.ViewModels;
|
||||
@@ -29,6 +30,7 @@ namespace Orchard.Roles.Drivers {
|
||||
_notifier = notifier;
|
||||
_authenticationService = authenticationService;
|
||||
_authorizationService = authorizationService;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
protected override string Prefix {
|
||||
@@ -37,6 +39,8 @@ namespace Orchard.Roles.Drivers {
|
||||
}
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
|
||||
protected override DriverResult Editor(UserRoles userRoles) {
|
||||
// don't show editor without apply roles permission
|
||||
if (!_authorizationService.TryCheckAccess(Permissions.ApplyRoles, _authenticationService.GetAuthenticatedUser(), userRoles))
|
||||
@@ -75,12 +79,12 @@ namespace Orchard.Roles.Drivers {
|
||||
var targetRoleRecords = model.Roles.Where(x => x.Granted).Select(x => _roleService.GetRole(x.RoleId));
|
||||
|
||||
foreach (var addingRole in targetRoleRecords.Where(x => !currentRoleRecords.Contains(x))) {
|
||||
_notifier.Warning(string.Format("Adding role {0} to user {1}", addingRole.Name, userRoles.As<IUser>().UserName));
|
||||
_notifier.Warning(T("Adding role {0} to user {1}", addingRole.Name, userRoles.As<IUser>().UserName));
|
||||
_userRolesRepository.Create(new UserRolesRecord { UserId = model.User.Id, Role = addingRole });
|
||||
}
|
||||
|
||||
foreach (var removingRole in currentUserRoleRecords.Where(x => !targetRoleRecords.Contains(x.Role))) {
|
||||
_notifier.Warning(string.Format("Removing role {0} from user {1}", removingRole.Role.Name, userRoles.As<IUser>().UserName));
|
||||
_notifier.Warning(T("Removing role {0} from user {1}", removingRole.Role.Name, userRoles.As<IUser>().UserName));
|
||||
_userRolesRepository.Delete(removingRole);
|
||||
}
|
||||
|
||||
|
@@ -7,7 +7,7 @@ namespace Orchard.Search {
|
||||
public string MenuName { get { return "admin"; } }
|
||||
|
||||
public void GetNavigation(NavigationBuilder builder) {
|
||||
builder.Add(T("Site"), "11",
|
||||
builder.Add(T("Site Configuration"), "11",
|
||||
menu => menu
|
||||
.Add(T("Search Index"), "10.0", item => item.Action("Index", "Admin", new {area = "Orchard.Search"})
|
||||
.Permission(Permissions.ManageSearchIndex)));
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user