--HG--
branch : dev
This commit is contained in:
Michael Dorian Bach
2010-07-30 11:14:45 -07:00
42 changed files with 293 additions and 109 deletions

View File

@@ -189,10 +189,10 @@ namespace Orchard.Tests.Modules.Indexing {
Assert.That(searchBuilder.Get(3).ContentItemId, Is.EqualTo(3)); Assert.That(searchBuilder.Get(3).ContentItemId, Is.EqualTo(3));
} }
[Test, Ignore("Fix pending")] [Test]
public void ProviderShouldStoreSettings() { public void ProviderShouldStoreSettings() {
_provider.CreateIndex("default"); _provider.CreateIndex("default");
Assert.That(_provider.GetLastIndexUtc("default"), Is.EqualTo(LuceneIndexProvider.DefaultMinDateTime)); Assert.That(_provider.GetLastIndexUtc("default"), Is.Null);
_provider.SetLastIndexUtc("default", new DateTime(2010, 1, 1, 1, 1, 1, 1)); _provider.SetLastIndexUtc("default", new DateTime(2010, 1, 1, 1, 1, 1, 1));
Assert.That(_provider.GetLastIndexUtc("default"), Is.EqualTo(new DateTime(2010, 1, 1, 1, 1, 1, 0))); Assert.That(_provider.GetLastIndexUtc("default"), Is.EqualTo(new DateTime(2010, 1, 1, 1, 1, 1, 0)));

View File

@@ -140,7 +140,7 @@ namespace Orchard.Tests.Modules.Indexing {
Assert.That(_searchBuilder.Slice(3, 3).Search().Count(), Is.EqualTo(2)); Assert.That(_searchBuilder.Slice(3, 3).Search().Count(), Is.EqualTo(2));
} }
[Test, Ignore("Fix pending")] [Test]
public void ShouldSortByRelevance() { public void ShouldSortByRelevance() {
_provider.CreateIndex("default"); _provider.CreateIndex("default");
_provider.Store("default", _provider.New(1).Add("body", "michael is in the kitchen").Analyze()); _provider.Store("default", _provider.New(1).Add("body", "michael is in the kitchen").Analyze());

View File

@@ -2,8 +2,10 @@
using System.Data.SqlClient; using System.Data.SqlClient;
using System.IO; using System.IO;
using Autofac.Features.Metadata; using Autofac.Features.Metadata;
using NHibernate.Tool.hbm2ddl;
using NUnit.Framework; using NUnit.Framework;
using Orchard.Data.Providers; using Orchard.Data.Providers;
using Orchard.Environment.Configuration;
using Orchard.Environment.Descriptor; using Orchard.Environment.Descriptor;
using Orchard.Environment.Descriptor.Models; using Orchard.Environment.Descriptor.Models;
using Orchard.Environment.ShellBuilders.Models; using Orchard.Environment.ShellBuilders.Models;
@@ -51,29 +53,35 @@ namespace Orchard.Tests.Data.Builders {
[Test, Ignore("Fix pending")] [Test, Ignore("Fix pending")]
public void SqlCeSchemaShouldBeGeneratedAndUsable() { public void SqlCeSchemaShouldBeGeneratedAndUsable() {
var recordDescriptors = new[] { var recordDescriptors = new[] {
new RecordBlueprint {TableName = "Hello", Type = typeof (FooRecord)} new RecordBlueprint {TableName = "Hello", Type = typeof (FooRecord)}
}; };
var parameters = new SessionFactoryParameters {
Provider = "SqlCe",
DataFolder = _tempDataFolder,
RecordDescriptors = recordDescriptors
};
var manager = (IDataServicesProviderFactory) new DataServicesProviderFactory(new[] { var manager = (IDataServicesProviderFactory) new DataServicesProviderFactory(new[] {
new Meta<CreateDataServicesProvider>( new Meta<CreateDataServicesProvider>(
(dataFolder, connectionString) => new SqlCeDataServicesProvider(dataFolder, connectionString), (dataFolder, connectionString) => new SqlCeDataServicesProvider(dataFolder, connectionString),
new Dictionary<string, object> {{"ProviderName", "SqlCe"}}) new Dictionary<string, object> {{"ProviderName", "SqlCe"}})
}); });
var parameters = new SessionFactoryParameters { var configuration = manager
Provider = "SqlCe",
DataFolder = _tempDataFolder,
RecordDescriptors = recordDescriptors
};
var sessionFactory = manager
.CreateProvider(parameters) .CreateProvider(parameters)
.BuildConfiguration(parameters) .BuildConfiguration(parameters);
.BuildSessionFactory();
configuration.SetProperty("connection.release_mode", "on_close");
new SchemaExport(configuration).Execute(false, true, false);
var sessionFactory = configuration.BuildSessionFactory();
var session = sessionFactory.OpenSession(); var session = sessionFactory.OpenSession();
var foo = new FooRecord {Name = "hi there"}; var foo = new FooRecord {Name = "hi there", Id = 1};
session.Save(foo); session.Save(foo);
session.Flush(); session.Flush();
session.Close(); session.Close();
@@ -104,12 +112,14 @@ namespace Orchard.Tests.Data.Builders {
ConnectionString = "Data Source=.\\SQLEXPRESS;AttachDbFileName=" + databasePath + ";Integrated Security=True;User Instance=True;", ConnectionString = "Data Source=.\\SQLEXPRESS;AttachDbFileName=" + databasePath + ";Integrated Security=True;User Instance=True;",
RecordDescriptors = recordDescriptors, RecordDescriptors = recordDescriptors,
}; };
var sessionFactory = manager
var configuration = manager
.CreateProvider(parameters) .CreateProvider(parameters)
.BuildConfiguration(parameters) .BuildConfiguration(parameters);
.BuildSessionFactory();
new SchemaExport(configuration).Execute(false, true, false);
var sessionFactory = configuration.BuildSessionFactory();
var session = sessionFactory.OpenSession(); var session = sessionFactory.OpenSession();
var foo = new FooRecord { Name = "hi there" }; var foo = new FooRecord { Name = "hi there" };

View File

@@ -10,6 +10,7 @@ using Autofac.Features.Indexed;
using Autofac.Features.Metadata; using Autofac.Features.Metadata;
using Castle.Core.Interceptor; using Castle.Core.Interceptor;
using NUnit.Framework; using NUnit.Framework;
using Orchard.Environment;
using Orchard.Environment.AutofacUtil.DynamicProxy2; using Orchard.Environment.AutofacUtil.DynamicProxy2;
using Orchard.Environment.Configuration; using Orchard.Environment.Configuration;
using Orchard.Environment.Extensions.Models; using Orchard.Environment.Extensions.Models;
@@ -26,6 +27,7 @@ namespace Orchard.Tests.Environment.ShellBuilders {
public void Init() { public void Init() {
var builder = new ContainerBuilder(); var builder = new ContainerBuilder();
builder.RegisterType<ShellContainerFactory>().As<IShellContainerFactory>(); builder.RegisterType<ShellContainerFactory>().As<IShellContainerFactory>();
builder.RegisterType<ShellContainerRegistrations>().As<IShellContainerRegistrations>();
builder.RegisterType<ComponentForHostContainer>(); builder.RegisterType<ComponentForHostContainer>();
builder.RegisterType<ControllerActionInvoker>().As<IActionInvoker>(); builder.RegisterType<ControllerActionInvoker>().As<IActionInvoker>();
_container = builder.Build(); _container = builder.Build();

View File

@@ -9,7 +9,7 @@ namespace Orchard.Core.Reports {
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Site Configuration"), "11", builder.Add(T("Site Configuration"), "11",
menu => menu.Add(T("Reports"), "0", item => item.Action("Index", "Admin", new { area = "Reports" }).Permission(StandardPermissions.AccessAdminPanel))); menu => menu.Add(T("Reports"), "15", item => item.Action("Index", "Admin", new { area = "Reports" }).Permission(StandardPermissions.AccessAdminPanel)));
} }
} }
} }

View File

@@ -9,7 +9,7 @@ namespace Orchard.Core.Settings {
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Site Configuration"), "11", builder.Add(T("Site Configuration"), "11",
menu => menu menu => menu
.Add(T("Settings"), "2.0", item => item.Action("Index", "Admin", new { area = "Settings" }).Permission(Permissions.ManageSettings))); .Add(T("Settings"), "10", item => item.Action("Index", "Admin", new { area = "Settings" }).Permission(Permissions.ManageSettings)));
} }
} }
} }

View File

@@ -14,7 +14,7 @@
<label for="SiteCulture"><%:T("Default Site Culture") %></label> <label for="SiteCulture"><%:T("Default Site Culture") %></label>
<%:Html.DropDownList("SiteCulture", new SelectList(Model.SiteCultures, Model.SiteCulture)) %> <%:Html.DropDownList("SiteCulture", new SelectList(Model.SiteCultures, Model.SiteCulture)) %>
<%:Html.ValidationMessage("SiteCulture", "*") %> <%:Html.ValidationMessage("SiteCulture", "*") %>
<%:Html.ActionLink(T("Add or remove supported cultures for the site.").ToString(), "Culture") %> <p><%:Html.ActionLink(T("Add or remove supported cultures for the site.").ToString(), "Culture") %></p>
</div> </div>
<div> <div>
<label for="PageTitleSeparator"><%:T("Page title separator") %></label> <label for="PageTitleSeparator"><%:T("Page title separator") %></label>

View File

@@ -125,7 +125,7 @@ namespace Lucene.Services {
.Delete(true); .Delete(true);
var settingsFileName = GetSettingsFileName(indexName); var settingsFileName = GetSettingsFileName(indexName);
if(File.Exists(settingsFileName)) { if (File.Exists(settingsFileName)) {
File.Delete(settingsFileName); File.Delete(settingsFileName);
} }
} }
@@ -139,7 +139,7 @@ namespace Lucene.Services {
} }
public void Store(string indexName, IEnumerable<LuceneDocumentIndex> indexDocuments) { public void Store(string indexName, IEnumerable<LuceneDocumentIndex> indexDocuments) {
if(indexDocuments.AsQueryable().Count() == 0) { if (indexDocuments.AsQueryable().Count() == 0) {
return; return;
} }
@@ -151,15 +151,15 @@ namespace Lucene.Services {
try { try {
foreach ( var indexDocument in indexDocuments ) { foreach (var indexDocument in indexDocuments) {
current = indexDocument; current = indexDocument;
var doc = CreateDocument(indexDocument); var doc = CreateDocument(indexDocument);
writer.AddDocument(doc); writer.AddDocument(doc);
Logger.Debug("Document [{0}] indexed", indexDocument.ContentItemId); Logger.Debug("Document [{0}] indexed", indexDocument.ContentItemId);
} }
} }
catch ( Exception ex ) { catch (Exception ex) {
Logger.Error(ex, "An unexpected error occured while add the document [{0}] from the index [{1}].", current.ContentItemId, indexName); Logger.Error(ex, "An unexpected error occured while add the document [{0}] from the index [{1}].", current.ContentItemId, indexName);
} }
finally { finally {

View File

@@ -47,6 +47,7 @@ namespace Lucene.Services {
InitPendingClause(); InitPendingClause();
} }
public ISearchBuilder Parse(string defaultField, string query) { public ISearchBuilder Parse(string defaultField, string query) {
return Parse(new string[] {defaultField}, query); return Parse(new string[] {defaultField}, query);
} }

View File

@@ -17,14 +17,12 @@ namespace Orchard.Blogs.Controllers {
private readonly IOrchardServices _services; private readonly IOrchardServices _services;
private readonly IBlogService _blogService; private readonly IBlogService _blogService;
private readonly IBlogSlugConstraint _blogSlugConstraint; private readonly IBlogSlugConstraint _blogSlugConstraint;
private readonly IFeedManager _feedManager;
private readonly RouteCollection _routeCollection; private readonly RouteCollection _routeCollection;
public BlogController(IOrchardServices services, IBlogService blogService, IBlogSlugConstraint blogSlugConstraint, IFeedManager feedManager, RouteCollection routeCollection) { public BlogController(IOrchardServices services, IBlogService blogService, IBlogSlugConstraint blogSlugConstraint, RouteCollection routeCollection) {
_services = services; _services = services;
_blogService = blogService; _blogService = blogService;
_blogSlugConstraint = blogSlugConstraint; _blogSlugConstraint = blogSlugConstraint;
_feedManager = feedManager;
_routeCollection = routeCollection; _routeCollection = routeCollection;
Logger = NullLogger.Instance; Logger = NullLogger.Instance;
} }
@@ -53,7 +51,6 @@ namespace Orchard.Blogs.Controllers {
Blog = _services.ContentManager.BuildDisplayModel(blog, "Detail") Blog = _services.ContentManager.BuildDisplayModel(blog, "Detail")
}; };
_feedManager.Register(blog);
return View(model); return View(model);
} }

View File

@@ -54,8 +54,6 @@ namespace Orchard.Blogs.Controllers {
BlogPost = _services.ContentManager.BuildDisplayModel(postPart, "Detail") BlogPost = _services.ContentManager.BuildDisplayModel(postPart, "Detail")
}; };
_feedManager.Register(blogPart);
return View(model); return View(model);
} }

View File

@@ -2,12 +2,14 @@
using System.Linq; using System.Linq;
using System.Web.Routing; using System.Web.Routing;
using JetBrains.Annotations; using JetBrains.Annotations;
using Orchard.Blogs.Extensions;
using Orchard.Blogs.Models; using Orchard.Blogs.Models;
using Orchard.Blogs.Services; using Orchard.Blogs.Services;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers; using Orchard.ContentManagement.Drivers;
using Orchard.Core.Contents.ViewModels; using Orchard.Core.Contents.ViewModels;
using Orchard.Core.ContentsLocation.Models; using Orchard.Core.ContentsLocation.Models;
using Orchard.Core.Feeds;
using Orchard.Localization; using Orchard.Localization;
using Orchard.Mvc.ViewModels; using Orchard.Mvc.ViewModels;
@@ -23,11 +25,13 @@ namespace Orchard.Blogs.Drivers {
private readonly IContentManager _contentManager; private readonly IContentManager _contentManager;
private readonly IBlogPostService _blogPostService; private readonly IBlogPostService _blogPostService;
private readonly IFeedManager _feedManager;
public BlogPartDriver(IOrchardServices services, IContentManager contentManager, IBlogPostService blogPostService) { public BlogPartDriver(IOrchardServices services, IContentManager contentManager, IBlogPostService blogPostService, IFeedManager feedManager) {
Services = services; Services = services;
_contentManager = contentManager; _contentManager = contentManager;
_blogPostService = blogPostService; _blogPostService = blogPostService;
_feedManager = feedManager;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
} }
@@ -71,6 +75,7 @@ namespace Orchard.Blogs.Drivers {
else if (displayType.StartsWith("Detail")) { else if (displayType.StartsWith("Detail")) {
blogPosts = _blogPostService.Get(blogPart) blogPosts = _blogPostService.Get(blogPart)
.Select(bp => _contentManager.BuildDisplayModel(bp, "Summary")); .Select(bp => _contentManager.BuildDisplayModel(bp, "Summary"));
_feedManager.Register(blogPart);
} }
return Combined( return Combined(

View File

@@ -1,13 +1,16 @@
using System.Web.Routing; using System.Web.Routing;
using JetBrains.Annotations; using JetBrains.Annotations;
using Orchard.Blogs.Models; using Orchard.Blogs.Models;
using Orchard.Blogs.Extensions;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers; using Orchard.ContentManagement.Drivers;
using Orchard.Core.Feeds;
using Orchard.Localization; using Orchard.Localization;
namespace Orchard.Blogs.Drivers { namespace Orchard.Blogs.Drivers {
[UsedImplicitly] [UsedImplicitly]
public class BlogPostPartDriver : ContentItemDriver<BlogPostPart> { public class BlogPostPartDriver : ContentItemDriver<BlogPostPart> {
private readonly IFeedManager _feedManager;
public IOrchardServices Services { get; set; } public IOrchardServices Services { get; set; }
public readonly static ContentType ContentType = new ContentType { public readonly static ContentType ContentType = new ContentType {
@@ -15,7 +18,8 @@ namespace Orchard.Blogs.Drivers {
DisplayName = "Blog Post" DisplayName = "Blog Post"
}; };
public BlogPostPartDriver(IOrchardServices services) { public BlogPostPartDriver(IOrchardServices services, IFeedManager feedManager) {
_feedManager = feedManager;
Services = services; Services = services;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
} }
@@ -70,6 +74,14 @@ namespace Orchard.Blogs.Drivers {
}; };
} }
protected override DriverResult Display(BlogPostPart part, string displayType) {
if (displayType.StartsWith("Detail")) {
_feedManager.Register(part.BlogPart);
}
return base.Display(part, displayType);
}
protected override DriverResult Editor(BlogPostPart postPart) { protected override DriverResult Editor(BlogPostPart postPart) {
return ContentItemTemplate("Items/Blogs.BlogPost"); return ContentItemTemplate("Items/Blogs.BlogPost");
} }

View File

@@ -8,6 +8,7 @@ description: The Orchard Blogs module is implementing basic blogging features.
features: features:
Orchard.Blogs: Orchard.Blogs:
Description: A simple web log. Description: A simple web log.
Dependencies: Feeds
Category: Content Category: Content
Remote Blog Publishing: Remote Blog Publishing:
Description: Blog easier using a dedicated MetaWeblogAPI-compatible publishing tool. Description: Blog easier using a dedicated MetaWeblogAPI-compatible publishing tool.

View File

@@ -12,7 +12,7 @@
} else { } else {
using (Html.BeginFormAntiForgeryPost(Url.Action("Close", new { commentedItemId = Model.CommentedItemId }), FormMethod.Post, new { @class = "inline" })) { %> using (Html.BeginFormAntiForgeryPost(Url.Action("Close", new { commentedItemId = Model.CommentedItemId }), FormMethod.Post, new { @class = "inline" })) { %>
<fieldset> <fieldset>
<button type="submit" class="remove" title="<%: T("Close Comments") %>"><%: T("Close Comments")%></button> <button type="submit" class="button primaryAction" title="<%: T("Close Comments") %>"><%: T("Close Comments")%></button>
</fieldset><% </fieldset><%
} }
} %> } %>
@@ -87,7 +87,7 @@
<td> <td>
<ul class="actions"> <ul class="actions">
<li class="construct"> <li class="construct">
<a href="<%: Url.Action("Edit", new {commentEntry.Comment.Id}) %>" class="ibutton edit" title="<%: T("Edit Comment")%>"><%: T("Edit Comment")%></a> <a href="<%: Url.Action("Edit", new {commentEntry.Comment.Id}) %>" title="<%: T("Edit Comment")%>"><%: T("Edit")%></a>
</li> </li>
<li class="destruct"> <li class="destruct">
<%-- a form in a form doesn't quite work <% using (Html.BeginFormAntiForgeryPost(Url.Action("Delete", new {id = commentEntry.Comment.Id, redirectToAction = "Details"}), FormMethod.Post, new { @class = "inline" })) { %> <%-- a form in a form doesn't quite work <% using (Html.BeginFormAntiForgeryPost(Url.Action("Delete", new {id = commentEntry.Comment.Id, redirectToAction = "Details"}), FormMethod.Post, new { @class = "inline" })) { %>
@@ -115,7 +115,7 @@
} else { } else {
using (Html.BeginFormAntiForgeryPost(Url.Action("Close", new { commentedItemId = Model.CommentedItemId }), FormMethod.Post, new { @class = "inline" })) { %> using (Html.BeginFormAntiForgeryPost(Url.Action("Close", new { commentedItemId = Model.CommentedItemId }), FormMethod.Post, new { @class = "inline" })) { %>
<fieldset> <fieldset>
<button type="submit" class="remove" title="<%: T("Close Comments") %>"><%: T("Close Comments")%></button> <button type="submit" class="button primaryAction" title="<%: T("Close Comments") %>"><%: T("Close Comments")%></button>
</fieldset><% </fieldset><%
} }
} %> } %>

View File

@@ -1,4 +1,5 @@
using Orchard.ContentManagement.Handlers; using Orchard.ContentManagement.FieldStorage.InfosetStorage;
using Orchard.ContentManagement.Handlers;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.Core.Common.Models; using Orchard.Core.Common.Models;
using Orchard.Tasks.Indexing; using Orchard.Tasks.Indexing;
@@ -21,16 +22,18 @@ namespace Orchard.Indexing.Handlers {
_indexingTaskManager = indexingTaskManager; _indexingTaskManager = indexingTaskManager;
_indexNotifierHandlers = indexNotifierHandlers; _indexNotifierHandlers = indexNotifierHandlers;
OnPublishing<ContentPart<CommonPartRecord>>(CreateIndexingTask); OnPublishing<ContentPart>(CreateIndexingTask);
OnRemoved<ContentPart<CommonPartRecord>>(RemoveIndexingTask); OnRemoved<ContentPart>(RemoveIndexingTask);
} }
void CreateIndexingTask(PublishContentContext context, ContentPart<CommonPartRecord> part) { void CreateIndexingTask(PublishContentContext context, ContentPart part) {
_indexingTaskManager.CreateUpdateIndexTask(context.ContentItem); _indexingTaskManager.CreateUpdateIndexTask(context.ContentItem);
// UpdateIndex();
} }
void RemoveIndexingTask(RemoveContentContext context, ContentPart<CommonPartRecord> part) { void RemoveIndexingTask(RemoveContentContext context, ContentPart part) {
_indexingTaskManager.CreateDeleteIndexTask(context.ContentItem); _indexingTaskManager.CreateDeleteIndexTask(context.ContentItem);
// UpdateIndex();
} }
private void UpdateIndex() { private void UpdateIndex() {

View File

@@ -13,15 +13,20 @@ namespace Orchard.Indexing.Handlers {
OnIndexing<InfosetPart>( OnIndexing<InfosetPart>(
(context, cp) => { (context, cp) => {
var infosetPart = context.ContentItem.As<InfosetPart>(); var infosetPart = context.ContentItem.As<InfosetPart>();
if ( infosetPart != null ) { if (infosetPart == null) {
foreach ( var part in infosetPart.ContentItem.Parts ) { return;
foreach ( var field in part.PartDefinition.Fields ) { }
if ( field.Settings.GetModel<FieldIndexing>().Included ) {
var fieldName = field.Name; // part fields
var value = part.Fields.Where(f => f.Name == fieldName).First().Storage.Get<string>(null); foreach ( var part in infosetPart.ContentItem.Parts ) {
context.DocumentIndex.Add(String.Format("{0}-{1}", infosetPart.TypeDefinition.Name, fieldName.ToLower()), value).RemoveTags().Analyze(); foreach ( var field in part.PartDefinition.Fields ) {
} if (!field.Settings.GetModel<FieldIndexing>().Included) {
continue;
} }
var fieldName = field.Name;
var value = part.Fields.Where(f => f.Name == fieldName).First().Storage.Get<string>(null);
context.DocumentIndex.Add(String.Format("{0}-{1}", infosetPart.TypeDefinition.Name.ToLower(), fieldName.ToLower()), value).RemoveTags().Analyze();
} }
} }
}); });

View File

@@ -103,8 +103,10 @@ namespace Orchard.Indexing.Services {
// nothing to do ? // nothing to do ?
if (taskRecords.Length + updateIndexDocuments.Count == 0) if (taskRecords.Length + updateIndexDocuments.Count == 0) {
Logger.Information("Index update requested, nothing to do");
return; return;
}
Logger.Information("Processing {0} indexing tasks", taskRecords.Length); Logger.Information("Processing {0} indexing tasks", taskRecords.Length);

View File

@@ -2,20 +2,25 @@
using Orchard.Environment; using Orchard.Environment;
using Orchard.Environment.Extensions; using Orchard.Environment.Extensions;
using Orchard.Environment.Extensions.Models; using Orchard.Environment.Extensions.Models;
using Orchard.Localization;
using Orchard.Packaging.Services; using Orchard.Packaging.Services;
using Orchard.UI.Notify;
namespace Orchard.Packaging { namespace Orchard.Packaging {
[OrchardFeature("Gallery")] [OrchardFeature("Gallery")]
public class DefaultPackagingUpdater : IFeatureEventHandler { public class DefaultPackagingUpdater : IFeatureEventHandler {
private readonly IPackagingSourceManager _packagingSourceManager; private readonly IPackagingSourceManager _packagingSourceManager;
private readonly INotifier _notifier;
public DefaultPackagingUpdater(IPackagingSourceManager packagingSourceManager) { public DefaultPackagingUpdater(IPackagingSourceManager packagingSourceManager, INotifier notifier) {
_packagingSourceManager = packagingSourceManager; _packagingSourceManager = packagingSourceManager;
_notifier = notifier;
} }
public Localizer T { get; set; }
public void Install(Feature feature) { public void Install(Feature feature) {
// add http://orchardproject.net/feeds/modules as the default Modules Feed _packagingSourceManager.AddSource(new PackagingSource { Id = Guid.NewGuid(), FeedTitle = "Orchard Module Gallery", FeedUrl = "http://orchardproject.net/gallery/feed" });
_packagingSourceManager.AddSource(new PackagingSource { Id = Guid.NewGuid(), FeedTitle = "Orchard Module Gallery", FeedUrl = "http://orchardproject.net/feeds/modules" });
} }
public void Enable(Feature feature) { public void Enable(Feature feature) {

View File

@@ -95,6 +95,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Module.txt" /> <Content Include="Module.txt" />
<Content Include="Styles\admin.css" />
<Content Include="Views\Gallery\AddSource.ascx" /> <Content Include="Views\Gallery\AddSource.ascx" />
<Content Include="Views\Gallery\Harvest.ascx" /> <Content Include="Views\Gallery\Harvest.ascx" />
<Content Include="Views\Gallery\Modules.ascx" /> <Content Include="Views\Gallery\Modules.ascx" />

View File

@@ -8,32 +8,38 @@ using System.Xml.Linq;
using System.Xml.Serialization; using System.Xml.Serialization;
using Orchard.Environment.Extensions; using Orchard.Environment.Extensions;
using Orchard.FileSystems.AppData; using Orchard.FileSystems.AppData;
using Orchard.Localization;
using Orchard.UI.Notify;
namespace Orchard.Packaging.Services { namespace Orchard.Packaging.Services {
[OrchardFeature("PackagingServices")] [OrchardFeature("PackagingServices")]
public class PackagingSourceManager : IPackagingSourceManager { public class PackagingSourceManager : IPackagingSourceManager {
private static readonly XmlSerializer _sourceSerializer = new XmlSerializer(typeof (List<PackagingSource>), new XmlRootAttribute("Sources")); private static readonly XmlSerializer _sourceSerializer = new XmlSerializer(typeof(List<PackagingSource>), new XmlRootAttribute("Sources"));
private readonly IAppDataFolder _appDataFolder; private readonly IAppDataFolder _appDataFolder;
private readonly INotifier _notifier;
public PackagingSourceManager(IAppDataFolder appDataFolder) { public PackagingSourceManager(IAppDataFolder appDataFolder, INotifier notifier) {
_appDataFolder = appDataFolder; _appDataFolder = appDataFolder;
_notifier = notifier;
T = NullLocalizer.Instance;
} }
Localizer T { get; set; }
#region IPackagingSourceManager Members #region IPackagingSourceManager Members
public IEnumerable<PackagingSource> GetSources() { public IEnumerable<PackagingSource> GetSources() {
string text = _appDataFolder.ReadFile(GetSourcesPath()); string text = _appDataFolder.ReadFile(GetSourcesPath());
if (string.IsNullOrEmpty(text)) { if ( string.IsNullOrEmpty(text) ) {
return Enumerable.Empty<PackagingSource>(); return Enumerable.Empty<PackagingSource>();
} }
var textReader = new StringReader(_appDataFolder.ReadFile(GetSourcesPath())); var textReader = new StringReader(_appDataFolder.ReadFile(GetSourcesPath()));
return (IEnumerable<PackagingSource>) _sourceSerializer.Deserialize(textReader); return (IEnumerable<PackagingSource>)_sourceSerializer.Deserialize(textReader);
} }
public void AddSource(PackagingSource source) { public void AddSource(PackagingSource source) {
UpdateSource(source); SaveSources(GetSources().Concat(new[] { source }).GroupBy(x => x.FeedUrl).Select(g => g.First()));
SaveSources(GetSources().Concat(new[] {source}));
} }
public void RemoveSource(Guid id) { public void RemoveSource(Guid id) {
@@ -41,16 +47,16 @@ namespace Orchard.Packaging.Services {
} }
public void UpdateLists() { public void UpdateLists() {
foreach (PackagingSource source in GetSources()) { foreach ( PackagingSource source in GetSources() ) {
UpdateSource(source); UpdateSource(source);
} }
} }
public IEnumerable<PackagingEntry> GetModuleList(PackagingSource packagingSource = null) { public IEnumerable<PackagingEntry> GetModuleList(PackagingSource packagingSource = null) {
IEnumerable<PackagingEntry> packageInfos = ( packagingSource == null ? GetSources() : new [] { packagingSource }) IEnumerable<PackagingEntry> packageInfos = ( packagingSource == null ? GetSources() : new[] { packagingSource } )
.SelectMany( .SelectMany(
source => source =>
Bind(ParseFeed(_appDataFolder.ReadFile(GetFeedCachePath(source))), Bind(ParseFeed(GetModuleListForSource(source)),
feed => feed =>
feed.Items.SelectMany( feed.Items.SelectMany(
item => item =>
@@ -65,6 +71,13 @@ namespace Orchard.Packaging.Services {
return packageInfos.ToArray(); return packageInfos.ToArray();
} }
private string GetModuleListForSource(PackagingSource source) {
if ( !_appDataFolder.FileExists(GetFeedCachePath(source)) ) {
UpdateSource(source);
}
return _appDataFolder.ReadFile(GetFeedCachePath(source));
}
#endregion #endregion
private static string GetSourcesPath() { private static string GetSourcesPath() {
@@ -83,8 +96,13 @@ namespace Orchard.Packaging.Services {
} }
private void UpdateSource(PackagingSource source) { private void UpdateSource(PackagingSource source) {
XDocument feed = XDocument.Load(source.FeedUrl, LoadOptions.PreserveWhitespace); try {
_appDataFolder.CreateFile(GetFeedCachePath(source), feed.ToString(SaveOptions.DisableFormatting)); XDocument feed = XDocument.Load(source.FeedUrl, LoadOptions.PreserveWhitespace);
_appDataFolder.CreateFile(GetFeedCachePath(source), feed.ToString(SaveOptions.DisableFormatting));
}
catch ( Exception e ) {
_notifier.Warning(T("Error loading content of feed '{0}': {1}", source.FeedUrl, e.Message));
}
} }
@@ -93,7 +111,7 @@ namespace Orchard.Packaging.Services {
} }
private static IEnumerable<T> Unit<T>(T t) where T : class { private static IEnumerable<T> Unit<T>(T t) where T : class {
return t != null ? new[] {t} : Enumerable.Empty<T>(); return t != null ? new[] { t } : Enumerable.Empty<T>();
} }
private static IEnumerable<T2> Bind<T, T2>(T t, Func<T, IEnumerable<T2>> f) where T : class { private static IEnumerable<T2> Bind<T, T2>(T t, Func<T, IEnumerable<T2>> f) where T : class {
@@ -101,6 +119,9 @@ namespace Orchard.Packaging.Services {
} }
private SyndicationFeed ParseFeed(string content) { private SyndicationFeed ParseFeed(string content) {
if ( string.IsNullOrEmpty(( content )) )
return new SyndicationFeed();
var formatter = new Atom10FeedFormatter<SyndicationFeed>(); var formatter = new Atom10FeedFormatter<SyndicationFeed>();
formatter.ReadFrom(XmlReader.Create(new StringReader(content))); formatter.ReadFrom(XmlReader.Create(new StringReader(content)));
return formatter.Feed; return formatter.Feed;

View File

@@ -0,0 +1,17 @@
.moduleName {
float:left;
}
.contentItems .related {
padding:1.2em 0.4em 0.5em
}
.contentItems .properties {
float:none;
clear:both;
}
.contentItems .pageStatus {
margin:.8em 0;
color:#666;
}

View File

@@ -1,4 +1,6 @@
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<Orchard.Packaging.ViewModels.PackagingModulesViewModel>" %> <%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<Orchard.Packaging.ViewModels.PackagingModulesViewModel>" %>
<% Html.RegisterStyle("admin.css"); %>
<h1> <h1>
<%: Html.TitleForPage(T("Browse Gallery").ToString())%></h1> <%: Html.TitleForPage(T("Browse Gallery").ToString())%></h1>
@@ -24,22 +26,23 @@
<% if (Model.Modules.Count() > 0) { %> <% if (Model.Modules.Count() > 0) { %>
<ul class="contentItems"> <ul class="contentItems">
<%foreach (var item in Model.Modules) {%> <%foreach (var item in Model.Modules) {%>
<li> <li>
<ul class="summary"> <div class="moduleName">
<div class="properties">
<h2><%: (item.SyndicationItem.Title == null ? T("(No title)").Text : item.SyndicationItem.Title.Text)%><span> - <%: T("Version: {0}", "1.0")%></span></h2> <h2><%: (item.SyndicationItem.Title == null ? T("(No title)").Text : item.SyndicationItem.Title.Text)%><span> - <%: T("Version: {0}", "1.0")%></span></h2>
<p><%: (item.SyndicationItem.Summary == null ? T("(No description").Text : item.SyndicationItem.Summary.Text) %></p>
<ul class="pageStatus" style="color:#666; margin:.6em 0 0 0;">
<li><%: T("Last Updated: {0}", item.SyndicationItem.LastUpdatedTime.ToLocalTime()) %></li>
<li>&nbsp;&#124;&nbsp;<%: T("Author: {0}", item.SyndicationItem.Authors.Any() ? String.Join(", ", item.SyndicationItem.Authors.Select(a => a.Name)) : T("Unknown").Text)%></li>
</ul>
</div> </div>
<div class="related"> <div class="related">
<%:Html.ActionLink(T("Install").ToString(), "Install", new RouteValueDictionary {{"SyndicationId",item.SyndicationItem.Id}})%><%:T(" | ") %> <%:Html.ActionLink(T("Install").ToString(), "Install", new RouteValueDictionary {{"SyndicationId",item.SyndicationItem.Id}})%><%:T(" | ") %>
<a href="<%:item.PackageStreamUri%>"><%: T("Download") %></a> <a href="<%:item.PackageStreamUri%>"><%: T("Download") %></a>
</div>
</div>
</ul> <div class="properties">
<p><%: (item.SyndicationItem.Summary == null ? T("(No description").Text : item.SyndicationItem.Summary.Text) %></p>
<ul class="pageStatus">
<li><%: T("Last Updated: {0}", item.SyndicationItem.LastUpdatedTime.ToLocalTime()) %></li>
<li>&nbsp;&#124;&nbsp;<%: T("Author: {0}", item.SyndicationItem.Authors.Any() ? String.Join(", ", item.SyndicationItem.Authors.Select(a => a.Name)) : T("Unknown").Text)%></li>
</ul>
</div>
</li><% </li><%
}%> }%>
</ul><% </ul><%

View File

@@ -50,7 +50,7 @@
<% } %> <% } %>
</fieldset> </fieldset>
<fieldset> <fieldset>
<input type="submit" class="button" name="submit.Save" value="<%: T("Save") %>" /> <input type="submit" class="button primaryAction" name="submit.Save" value="<%: T("Save") %>" />
<input type="submit" class="button remove" name="submit.Delete" value="<%: T("Remove") %>" /> <input type="submit" class="button" name="submit.Delete" value="<%: T("Remove") %>" />
</fieldset> </fieldset>
<% } %> <% } %>

View File

@@ -8,7 +8,7 @@
border-color:#8f8f8f; border-color:#8f8f8f;
} }
.managewrapper { .managewrapper {
overflow:hidden; padding:2px 0;
position:relative; position:relative;
} }
.managewrapper .manage { .managewrapper .manage {
@@ -20,6 +20,7 @@
overflow:hidden; overflow:hidden;
position:absolute; position:absolute;
right:0; right:0;
top:0;
} }
.managewrapper:hover .manage { .managewrapper:hover .manage {
display:block; display:block;

View File

@@ -1,7 +1,13 @@
using Orchard.Tasks; using Orchard.Tasks;
namespace Orchard.Commands { namespace Orchard.Commands {
public class CommandBackgroundService : IBackgroundService { /// <summary>
/// Command line specific "no-op" background service implementation.
/// Note that we make this class "internal" so that it's not auto-registered
/// by the Orchard Framework (it is registered explicitly by the command
/// line host).
/// </summary>
internal class CommandBackgroundService : IBackgroundService {
public void Sweep() { public void Sweep() {
// Don't run any background service in command line // Don't run any background service in command line
} }

View File

@@ -5,6 +5,7 @@ using System.Linq;
using System.Web.Mvc; using System.Web.Mvc;
using System.Web.Routing; using System.Web.Routing;
using Autofac; using Autofac;
using Orchard.Caching;
using Orchard.Environment; using Orchard.Environment;
using Orchard.Environment.Configuration; using Orchard.Environment.Configuration;
using Orchard.Environment.State; using Orchard.Environment.State;
@@ -152,9 +153,24 @@ namespace Orchard.Commands {
protected void ContainerRegistrations(ContainerBuilder builder) { protected void ContainerRegistrations(ContainerBuilder builder) {
MvcSingletons(builder); MvcSingletons(builder);
builder.RegisterType<CommandHostEnvironment>().As<IHostEnvironment>();
builder.RegisterType<CommandBackgroundService>().As<IBackgroundService>(); builder.RegisterType<CommandHostEnvironment>().As<IHostEnvironment>().SingleInstance();
builder.RegisterType<CommandHostVirtualPathMonitor>().As<IVirtualPathMonitor>(); builder.RegisterType<CommandHostVirtualPathMonitor>().As<IVirtualPathMonitor>().As<IVolatileProvider>().SingleInstance();
builder.RegisterInstance(CreateShellRegistrations()).As<IShellContainerRegistrations>();
}
private CommandHostShellContainerRegistrations CreateShellRegistrations() {
return new CommandHostShellContainerRegistrations {
Registrations = shellBuilder => {
shellBuilder.RegisterType<CommandHostVirtualPathMonitor>()
.As<IVirtualPathMonitor>()
.As<IVolatileProvider>()
.InstancePerMatchingLifetimeScope("shell");
shellBuilder.RegisterType<CommandBackgroundService>()
.As<IBackgroundService>()
.InstancePerLifetimeScope();
}
};
} }
protected void MvcSingletons(ContainerBuilder builder) { protected void MvcSingletons(ContainerBuilder builder) {
@@ -164,5 +180,9 @@ namespace Orchard.Commands {
builder.RegisterInstance(ModelMetadataProviders.Current); builder.RegisterInstance(ModelMetadataProviders.Current);
builder.RegisterInstance(ViewEngines.Engines); builder.RegisterInstance(ViewEngines.Engines);
} }
private class CommandHostShellContainerRegistrations : IShellContainerRegistrations {
public Action<ContainerBuilder> Registrations { get; set; }
}
} }
} }

View File

@@ -5,7 +5,7 @@ using Orchard.Environment;
using Orchard.Localization; using Orchard.Localization;
namespace Orchard.Commands { namespace Orchard.Commands {
public class CommandHostEnvironment : IHostEnvironment { internal class CommandHostEnvironment : IHostEnvironment {
public CommandHostEnvironment() { public CommandHostEnvironment() {
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
} }

View File

@@ -1,12 +1,16 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using Orchard.Caching; using Orchard.Caching;
using Orchard.FileSystems.VirtualPath; using Orchard.FileSystems.VirtualPath;
namespace Orchard.Commands { namespace Orchard.Commands {
public class CommandHostVirtualPathMonitor : IVirtualPathMonitor { /// <summary>
/// Command line specific virtual path monitor.
/// Note that we make this class "internal" so that it's not auto-registered
/// by the Orchard Framework (it is registered explicitly by the command
/// line host).
/// </summary>
internal class CommandHostVirtualPathMonitor : IVirtualPathMonitor {
private readonly IVirtualPathProvider _virtualPathProvider; private readonly IVirtualPathProvider _virtualPathProvider;
public CommandHostVirtualPathMonitor(IVirtualPathProvider virtualPathProvider) { public CommandHostVirtualPathMonitor(IVirtualPathProvider virtualPathProvider) {

View File

@@ -105,6 +105,9 @@ namespace Orchard.Data {
private Hash ComputeHash() { private Hash ComputeHash() {
var hash = new Hash(); var hash = new Hash();
hash.AddString(_shellSettings.DataProvider);
hash.AddString(_shellSettings.DataTablePrefix);
hash.AddString(_shellSettings.DataConnectionString);
hash.AddString(_shellSettings.Name); hash.AddString(_shellSettings.Name);
// We need to hash the assemnly names, record names and property names // We need to hash the assemnly names, record names and property names

View File

@@ -1,6 +1,5 @@
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Web;
using System.Web.Mvc; using System.Web.Mvc;
using System.Collections.Generic; using System.Collections.Generic;
using Orchard.Caching; using Orchard.Caching;
@@ -19,9 +18,9 @@ using Orchard.Utility.Extensions;
namespace Orchard.Environment { namespace Orchard.Environment {
public class DefaultOrchardHost : IOrchardHost, IShellSettingsManagerEventHandler, IShellDescriptorManagerEventHandler { public class DefaultOrchardHost : IOrchardHost, IShellSettingsManagerEventHandler, IShellDescriptorManagerEventHandler {
private readonly ControllerBuilder _controllerBuilder; private readonly ControllerBuilder _controllerBuilder;
private readonly IHostLocalRestart _hostLocalRestart;
private readonly IShellSettingsManager _shellSettingsManager; private readonly IShellSettingsManager _shellSettingsManager;
private readonly IShellContextFactory _shellContextFactory; private readonly IShellContextFactory _shellContextFactory;
private readonly IShellDescriptorCache _shellDescriptorCache;
private readonly IRunningShellTable _runningShellTable; private readonly IRunningShellTable _runningShellTable;
private readonly IProcessingEngine _processingEngine; private readonly IProcessingEngine _processingEngine;
private readonly IExtensionLoaderCoordinator _extensionLoaderCoordinator; private readonly IExtensionLoaderCoordinator _extensionLoaderCoordinator;
@@ -33,21 +32,21 @@ namespace Orchard.Environment {
public DefaultOrchardHost( public DefaultOrchardHost(
IShellSettingsManager shellSettingsManager, IShellSettingsManager shellSettingsManager,
IShellContextFactory shellContextFactory, IShellContextFactory shellContextFactory,
IShellDescriptorCache shellDescriptorCache,
IRunningShellTable runningShellTable, IRunningShellTable runningShellTable,
IProcessingEngine processingEngine, IProcessingEngine processingEngine,
IExtensionLoaderCoordinator extensionLoaderCoordinator, IExtensionLoaderCoordinator extensionLoaderCoordinator,
ICacheManager cacheManager, ICacheManager cacheManager,
ControllerBuilder controllerBuilder) { ControllerBuilder controllerBuilder,
IHostLocalRestart hostLocalRestart ) {
_shellSettingsManager = shellSettingsManager; _shellSettingsManager = shellSettingsManager;
_shellContextFactory = shellContextFactory; _shellContextFactory = shellContextFactory;
_shellDescriptorCache = shellDescriptorCache;
_runningShellTable = runningShellTable; _runningShellTable = runningShellTable;
_processingEngine = processingEngine; _processingEngine = processingEngine;
_extensionLoaderCoordinator = extensionLoaderCoordinator; _extensionLoaderCoordinator = extensionLoaderCoordinator;
_cacheManager = cacheManager; _cacheManager = cacheManager;
_controllerBuilder = controllerBuilder; _controllerBuilder = controllerBuilder;
_hostLocalRestart = hostLocalRestart;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
Logger = NullLogger.Instance; Logger = NullLogger.Instance;
@@ -152,7 +151,7 @@ namespace Orchard.Environment {
_cacheManager.Get("OrchardHost_Extensions", _cacheManager.Get("OrchardHost_Extensions",
ctx => { ctx => {
_extensionLoaderCoordinator.MonitorExtensions(ctx.Monitor); _extensionLoaderCoordinator.MonitorExtensions(ctx.Monitor);
_shellDescriptorCache.Monitor(ctx.Monitor); _hostLocalRestart.Monitor(ctx.Monitor);
_current = null; _current = null;
return ""; return "";
}); });

View File

@@ -27,11 +27,6 @@ namespace Orchard.Environment.Descriptor {
/// Loss of storage is expected. /// Loss of storage is expected.
/// </summary> /// </summary>
void Store(string shellName, ShellDescriptor descriptor); void Store(string shellName, ShellDescriptor descriptor);
/// <summary>
/// Monitor changes on the persistent storage.
/// </summary>
void Monitor(Action<IVolatileToken> monitor);
} }
public class ShellDescriptorCache : IShellDescriptorCache { public class ShellDescriptorCache : IShellDescriptorCache {
@@ -104,10 +99,6 @@ namespace Orchard.Environment.Descriptor {
_appDataFolder.CreateFile(DescriptorCacheFileName, saveWriter.ToString()); _appDataFolder.CreateFile(DescriptorCacheFileName, saveWriter.ToString());
} }
public void Monitor(Action<IVolatileToken> monitor) {
monitor(_appDataFolder.WhenPathChanges(DescriptorCacheFileName));
}
#endregion #endregion
private void VerifyCacheFile() { private void VerifyCacheFile() {

View File

@@ -0,0 +1,52 @@
using System;
using Orchard.Caching;
using Orchard.Environment.Configuration;
using Orchard.Environment.Descriptor;
using Orchard.Environment.Descriptor.Models;
using Orchard.FileSystems.AppData;
using Orchard.Logging;
namespace Orchard.Environment {
public interface IHostLocalRestart {
/// <summary>
/// Monitor changes on the persistent storage.
/// </summary>
void Monitor(Action<IVolatileToken> monitor);
}
public class DefaultHostLocalRestart : IHostLocalRestart, IShellDescriptorManagerEventHandler, IShellSettingsManagerEventHandler {
private readonly IAppDataFolder _appDataFolder;
private const string fileName = "hrestart.txt";
public DefaultHostLocalRestart(IAppDataFolder appDataFolder) {
_appDataFolder = appDataFolder;
Logger = NullLogger.Instance;
}
public ILogger Logger { get; set; }
public void Monitor(Action<IVolatileToken> monitor) {
if (!_appDataFolder.FileExists(fileName))
TouchFile();
monitor(_appDataFolder.WhenPathChanges(fileName));
}
void IShellSettingsManagerEventHandler.Saved(ShellSettings settings) {
TouchFile();
}
void IShellDescriptorManagerEventHandler.Changed(ShellDescriptor descriptor) {
TouchFile();
}
private void TouchFile() {
try {
_appDataFolder.CreateFile(fileName, "Host Restart");
}
catch(Exception e) {
Logger.Warning("Error updateting file '{0}': {1}", fileName, e.Message);
}
}
}
}

View File

@@ -0,0 +1,16 @@
using System;
using Autofac;
namespace Orchard.Environment {
public interface IShellContainerRegistrations {
Action<ContainerBuilder> Registrations { get; }
}
public class ShellContainerRegistrations : IShellContainerRegistrations {
public ShellContainerRegistrations() {
Registrations = builder => { return; };
}
public Action<ContainerBuilder> Registrations { get; private set; }
}
}

View File

@@ -6,7 +6,6 @@ using System.Web.Hosting;
using Autofac; using Autofac;
using Autofac.Configuration; using Autofac.Configuration;
using Orchard.Caching; using Orchard.Caching;
using Orchard.Data;
using Orchard.Environment.AutofacUtil; using Orchard.Environment.AutofacUtil;
using Orchard.Environment.Configuration; using Orchard.Environment.Configuration;
using Orchard.Environment.Extensions; using Orchard.Environment.Extensions;
@@ -36,6 +35,7 @@ namespace Orchard.Environment {
builder.RegisterType<DefaultOrchardEventBus>().As<IEventBus>().SingleInstance(); builder.RegisterType<DefaultOrchardEventBus>().As<IEventBus>().SingleInstance();
builder.RegisterType<DefaultCacheHolder>().As<ICacheHolder>().SingleInstance(); builder.RegisterType<DefaultCacheHolder>().As<ICacheHolder>().SingleInstance();
builder.RegisterType<DefaultHostEnvironment>().As<IHostEnvironment>().SingleInstance(); builder.RegisterType<DefaultHostEnvironment>().As<IHostEnvironment>().SingleInstance();
builder.RegisterType<DefaultHostLocalRestart>().As<IHostLocalRestart>().SingleInstance();
builder.RegisterType<DefaultBuildManager>().As<IBuildManager>().SingleInstance(); builder.RegisterType<DefaultBuildManager>().As<IBuildManager>().SingleInstance();
builder.RegisterType<WebFormVirtualPathProvider>().As<ICustomVirtualPathProvider>().SingleInstance(); builder.RegisterType<WebFormVirtualPathProvider>().As<ICustomVirtualPathProvider>().SingleInstance();
builder.RegisterType<DynamicModuleVirtualPathProvider>().As<ICustomVirtualPathProvider>().SingleInstance(); builder.RegisterType<DynamicModuleVirtualPathProvider>().As<ICustomVirtualPathProvider>().SingleInstance();
@@ -63,6 +63,7 @@ namespace Orchard.Environment {
.As<ICompositionStrategy>() .As<ICompositionStrategy>()
.SingleInstance(); .SingleInstance();
{ {
builder.RegisterType<ShellContainerRegistrations>().As<IShellContainerRegistrations>().SingleInstance();
builder.RegisterType<ExtensionLoaderCoordinator>().As<IExtensionLoaderCoordinator>().SingleInstance(); builder.RegisterType<ExtensionLoaderCoordinator>().As<IExtensionLoaderCoordinator>().SingleInstance();
builder.RegisterType<ExtensionManager>().As<IExtensionManager>().SingleInstance(); builder.RegisterType<ExtensionManager>().As<IExtensionManager>().SingleInstance();
{ {

View File

@@ -11,7 +11,6 @@ using Autofac.Features.Indexed;
using Autofac.Integration.Web.Mvc; using Autofac.Integration.Web.Mvc;
using Orchard.Environment.AutofacUtil.DynamicProxy2; using Orchard.Environment.AutofacUtil.DynamicProxy2;
using Orchard.Environment.Configuration; using Orchard.Environment.Configuration;
using Orchard.Environment.Descriptor.Models;
using Orchard.Environment.ShellBuilders.Models; using Orchard.Environment.ShellBuilders.Models;
using Orchard.Events; using Orchard.Events;
@@ -23,9 +22,11 @@ namespace Orchard.Environment.ShellBuilders {
public class ShellContainerFactory : IShellContainerFactory { public class ShellContainerFactory : IShellContainerFactory {
private readonly ILifetimeScope _lifetimeScope; private readonly ILifetimeScope _lifetimeScope;
private readonly IShellContainerRegistrations _shellContainerRegistrations;
public ShellContainerFactory(ILifetimeScope lifetimeScope) { public ShellContainerFactory(ILifetimeScope lifetimeScope, IShellContainerRegistrations shellContainerRegistrations) {
_lifetimeScope = lifetimeScope; _lifetimeScope = lifetimeScope;
_shellContainerRegistrations = shellContainerRegistrations;
} }
public ILifetimeScope CreateContainer(ShellSettings settings, ShellBlueprint blueprint) { public ILifetimeScope CreateContainer(ShellSettings settings, ShellBlueprint blueprint) {
@@ -95,6 +96,9 @@ namespace Orchard.Environment.ShellBuilders {
.InjectActionInvoker(); .InjectActionInvoker();
} }
// Register code-only registrations specific to a shell
_shellContainerRegistrations.Registrations(builder);
var optionalShellConfig = HostingEnvironment.MapPath("~/Config/Sites.config"); var optionalShellConfig = HostingEnvironment.MapPath("~/Config/Sites.config");
if (File.Exists(optionalShellConfig)) if (File.Exists(optionalShellConfig))
builder.RegisterModule(new ConfigurationSettingsReader(ConfigurationSettingsReader.DefaultSectionName, optionalShellConfig)); builder.RegisterModule(new ConfigurationSettingsReader(ConfigurationSettingsReader.DefaultSectionName, optionalShellConfig));

View File

@@ -3,7 +3,7 @@ using System.Collections.Generic;
using Orchard.ContentManagement; using Orchard.ContentManagement;
namespace Orchard.Indexing { namespace Orchard.Indexing {
public interface IIndexProvider : IDependency { public interface IIndexProvider : ISingletonDependency {
/// <summary> /// <summary>
/// Creates a new index /// Creates a new index
/// </summary> /// </summary>
@@ -62,7 +62,7 @@ namespace Orchard.Indexing {
ISearchBuilder CreateSearchBuilder(string indexName); ISearchBuilder CreateSearchBuilder(string indexName);
/// <summary> /// <summary>
/// Returns the date and time when the index was last processed /// Returns the date and time when the index was last processed, or null if the index doesn't exist
/// </summary> /// </summary>
DateTime? GetLastIndexUtc(string indexName); DateTime? GetLastIndexUtc(string indexName);

View File

@@ -368,6 +368,8 @@
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="ContentManagement\DataMigrations\FrameworkDataMigration.cs" /> <Compile Include="ContentManagement\DataMigrations\FrameworkDataMigration.cs" />
<Compile Include="Environment\IHostLocalRestart.cs" />
<Compile Include="Environment\IShellContainerRegistrations.cs" />
<Compile Include="FileSystems\Dependencies\DynamicModuleVirtualPathProvider.cs" /> <Compile Include="FileSystems\Dependencies\DynamicModuleVirtualPathProvider.cs" />
<Compile Include="Services\IHtmlFilter.cs" /> <Compile Include="Services\IHtmlFilter.cs" />
<Compile Include="Utility\Hash.cs" /> <Compile Include="Utility\Hash.cs" />

View File

@@ -12,6 +12,8 @@ namespace Orchard.Utility {
public string Value { get { return _hash.ToString(); } } public string Value { get { return _hash.ToString(); } }
public void AddString(string value) { public void AddString(string value) {
if ( string.IsNullOrEmpty(value) )
return;
_hash += value.GetHashCode(); _hash += value.GetHashCode();
} }

View File

@@ -15,13 +15,13 @@ using PackageIndexReferenceImplementation.Services;
namespace PackageIndexReferenceImplementation.Controllers { namespace PackageIndexReferenceImplementation.Controllers {
[HandleError] [HandleError]
public class ModulesController : Controller { public class FeedController : Controller {
private readonly FeedStorage _feedStorage; private readonly FeedStorage _feedStorage;
private readonly MediaStorage _mediaStorage; private readonly MediaStorage _mediaStorage;
public IMembershipService MembershipService { get; set; } public IMembershipService MembershipService { get; set; }
public ModulesController() { public FeedController() {
_feedStorage = new FeedStorage(); _feedStorage = new FeedStorage();
_mediaStorage = new MediaStorage(); _mediaStorage = new MediaStorage();
if ( MembershipService == null ) { MembershipService = new AccountMembershipService(); } if ( MembershipService == null ) { MembershipService = new AccountMembershipService(); }

View File

@@ -72,7 +72,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Controllers\AccountController.cs" /> <Compile Include="Controllers\AccountController.cs" />
<Compile Include="Controllers\ModulesController.cs" /> <Compile Include="Controllers\FeedController.cs" />
<Compile Include="Controllers\Artifacts\AtomFeedResult.cs" /> <Compile Include="Controllers\Artifacts\AtomFeedResult.cs" />
<Compile Include="Controllers\Artifacts\AtomItemResult.cs" /> <Compile Include="Controllers\Artifacts\AtomItemResult.cs" />
<Compile Include="Controllers\Artifacts\ContentTypeAttribute.cs" /> <Compile Include="Controllers\Artifacts\ContentTypeAttribute.cs" />

View File

@@ -7,7 +7,7 @@
<asp:Content ID="loginContent" ContentPlaceHolderID="MainContent" runat="server"> <asp:Content ID="loginContent" ContentPlaceHolderID="MainContent" runat="server">
<h2>Log On</h2> <h2>Log On</h2>
<p> <p>
Please enter your username and password. <%: Html.ActionLink("Register", "Register") %> if you don't have an account. Please enter your username and password.
</p> </p>
<% using (Html.BeginForm()) { %> <% using (Html.BeginForm()) { %>