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

View File

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

View File

@@ -9,7 +9,7 @@ namespace Orchard.Core.Reports {
public void GetNavigation(NavigationBuilder builder) {
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) {
builder.Add(T("Site Configuration"), "11",
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>
<%:Html.DropDownList("SiteCulture", new SelectList(Model.SiteCultures, Model.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>
<label for="PageTitleSeparator"><%:T("Page title separator") %></label>

View File

@@ -125,7 +125,7 @@ namespace Lucene.Services {
.Delete(true);
var settingsFileName = GetSettingsFileName(indexName);
if(File.Exists(settingsFileName)) {
if (File.Exists(settingsFileName)) {
File.Delete(settingsFileName);
}
}
@@ -139,7 +139,7 @@ namespace Lucene.Services {
}
public void Store(string indexName, IEnumerable<LuceneDocumentIndex> indexDocuments) {
if(indexDocuments.AsQueryable().Count() == 0) {
if (indexDocuments.AsQueryable().Count() == 0) {
return;
}
@@ -151,15 +151,15 @@ namespace Lucene.Services {
try {
foreach ( var indexDocument in indexDocuments ) {
foreach (var indexDocument in indexDocuments) {
current = indexDocument;
var doc = CreateDocument(indexDocument);
writer.AddDocument(doc);
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);
}
finally {

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,13 +1,16 @@
using System.Web.Routing;
using JetBrains.Annotations;
using Orchard.Blogs.Models;
using Orchard.Blogs.Extensions;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.Core.Feeds;
using Orchard.Localization;
namespace Orchard.Blogs.Drivers {
[UsedImplicitly]
public class BlogPostPartDriver : ContentItemDriver<BlogPostPart> {
private readonly IFeedManager _feedManager;
public IOrchardServices Services { get; set; }
public readonly static ContentType ContentType = new ContentType {
@@ -15,7 +18,8 @@ namespace Orchard.Blogs.Drivers {
DisplayName = "Blog Post"
};
public BlogPostPartDriver(IOrchardServices services) {
public BlogPostPartDriver(IOrchardServices services, IFeedManager feedManager) {
_feedManager = feedManager;
Services = services;
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) {
return ContentItemTemplate("Items/Blogs.BlogPost");
}

View File

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

View File

@@ -12,7 +12,7 @@
} else {
using (Html.BeginFormAntiForgeryPost(Url.Action("Close", new { commentedItemId = Model.CommentedItemId }), FormMethod.Post, new { @class = "inline" })) { %>
<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><%
}
} %>
@@ -87,7 +87,7 @@
<td>
<ul class="actions">
<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 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" })) { %>
@@ -115,7 +115,7 @@
} else {
using (Html.BeginFormAntiForgeryPost(Url.Action("Close", new { commentedItemId = Model.CommentedItemId }), FormMethod.Post, new { @class = "inline" })) { %>
<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><%
}
} %>

View File

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

View File

@@ -13,15 +13,20 @@ namespace Orchard.Indexing.Handlers {
OnIndexing<InfosetPart>(
(context, cp) => {
var infosetPart = context.ContentItem.As<InfosetPart>();
if ( infosetPart != null ) {
foreach ( var part in infosetPart.ContentItem.Parts ) {
foreach ( var field in part.PartDefinition.Fields ) {
if ( field.Settings.GetModel<FieldIndexing>().Included ) {
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, fieldName.ToLower()), value).RemoveTags().Analyze();
}
if (infosetPart == null) {
return;
}
// part fields
foreach ( var part in infosetPart.ContentItem.Parts ) {
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 ?
if (taskRecords.Length + updateIndexDocuments.Count == 0)
if (taskRecords.Length + updateIndexDocuments.Count == 0) {
Logger.Information("Index update requested, nothing to do");
return;
}
Logger.Information("Processing {0} indexing tasks", taskRecords.Length);

View File

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

View File

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

View File

@@ -8,32 +8,38 @@ using System.Xml.Linq;
using System.Xml.Serialization;
using Orchard.Environment.Extensions;
using Orchard.FileSystems.AppData;
using Orchard.Localization;
using Orchard.UI.Notify;
namespace Orchard.Packaging.Services {
[OrchardFeature("PackagingServices")]
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 INotifier _notifier;
public PackagingSourceManager(IAppDataFolder appDataFolder) {
public PackagingSourceManager(IAppDataFolder appDataFolder, INotifier notifier) {
_appDataFolder = appDataFolder;
_notifier = notifier;
T = NullLocalizer.Instance;
}
Localizer T { get; set; }
#region IPackagingSourceManager Members
public IEnumerable<PackagingSource> GetSources() {
string text = _appDataFolder.ReadFile(GetSourcesPath());
if (string.IsNullOrEmpty(text)) {
if ( string.IsNullOrEmpty(text) ) {
return Enumerable.Empty<PackagingSource>();
}
var textReader = new StringReader(_appDataFolder.ReadFile(GetSourcesPath()));
return (IEnumerable<PackagingSource>) _sourceSerializer.Deserialize(textReader);
return (IEnumerable<PackagingSource>)_sourceSerializer.Deserialize(textReader);
}
public void AddSource(PackagingSource source) {
UpdateSource(source);
SaveSources(GetSources().Concat(new[] {source}));
SaveSources(GetSources().Concat(new[] { source }).GroupBy(x => x.FeedUrl).Select(g => g.First()));
}
public void RemoveSource(Guid id) {
@@ -41,16 +47,16 @@ namespace Orchard.Packaging.Services {
}
public void UpdateLists() {
foreach (PackagingSource source in GetSources()) {
foreach ( PackagingSource source in GetSources() ) {
UpdateSource(source);
}
}
public IEnumerable<PackagingEntry> GetModuleList(PackagingSource packagingSource = null) {
IEnumerable<PackagingEntry> packageInfos = ( packagingSource == null ? GetSources() : new [] { packagingSource })
IEnumerable<PackagingEntry> packageInfos = ( packagingSource == null ? GetSources() : new[] { packagingSource } )
.SelectMany(
source =>
Bind(ParseFeed(_appDataFolder.ReadFile(GetFeedCachePath(source))),
Bind(ParseFeed(GetModuleListForSource(source)),
feed =>
feed.Items.SelectMany(
item =>
@@ -65,6 +71,13 @@ namespace Orchard.Packaging.Services {
return packageInfos.ToArray();
}
private string GetModuleListForSource(PackagingSource source) {
if ( !_appDataFolder.FileExists(GetFeedCachePath(source)) ) {
UpdateSource(source);
}
return _appDataFolder.ReadFile(GetFeedCachePath(source));
}
#endregion
private static string GetSourcesPath() {
@@ -83,8 +96,13 @@ namespace Orchard.Packaging.Services {
}
private void UpdateSource(PackagingSource source) {
XDocument feed = XDocument.Load(source.FeedUrl, LoadOptions.PreserveWhitespace);
_appDataFolder.CreateFile(GetFeedCachePath(source), feed.ToString(SaveOptions.DisableFormatting));
try {
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 {
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 {
@@ -101,6 +119,9 @@ namespace Orchard.Packaging.Services {
}
private SyndicationFeed ParseFeed(string content) {
if ( string.IsNullOrEmpty(( content )) )
return new SyndicationFeed();
var formatter = new Atom10FeedFormatter<SyndicationFeed>();
formatter.ReadFrom(XmlReader.Create(new StringReader(content)));
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>" %>
<% Html.RegisterStyle("admin.css"); %>
<h1>
<%: Html.TitleForPage(T("Browse Gallery").ToString())%></h1>
@@ -24,22 +26,23 @@
<% if (Model.Modules.Count() > 0) { %>
<ul class="contentItems">
<%foreach (var item in Model.Modules) {%>
<li>
<ul class="summary">
<div class="properties">
<li>
<div class="moduleName">
<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 class="related">
<%:Html.ActionLink(T("Install").ToString(), "Install", new RouteValueDictionary {{"SyndicationId",item.SyndicationItem.Id}})%><%:T(" | ") %>
<a href="<%:item.PackageStreamUri%>"><%: T("Download") %></a>
</div>
</ul>
</div>
<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><%
}%>
</ul><%

View File

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

View File

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

View File

@@ -1,7 +1,13 @@
using Orchard.Tasks;
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() {
// 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.Routing;
using Autofac;
using Orchard.Caching;
using Orchard.Environment;
using Orchard.Environment.Configuration;
using Orchard.Environment.State;
@@ -152,9 +153,24 @@ namespace Orchard.Commands {
protected void ContainerRegistrations(ContainerBuilder builder) {
MvcSingletons(builder);
builder.RegisterType<CommandHostEnvironment>().As<IHostEnvironment>();
builder.RegisterType<CommandBackgroundService>().As<IBackgroundService>();
builder.RegisterType<CommandHostVirtualPathMonitor>().As<IVirtualPathMonitor>();
builder.RegisterType<CommandHostEnvironment>().As<IHostEnvironment>().SingleInstance();
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) {
@@ -164,5 +180,9 @@ namespace Orchard.Commands {
builder.RegisterInstance(ModelMetadataProviders.Current);
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;
namespace Orchard.Commands {
public class CommandHostEnvironment : IHostEnvironment {
internal class CommandHostEnvironment : IHostEnvironment {
public CommandHostEnvironment() {
T = NullLocalizer.Instance;
}

View File

@@ -1,12 +1,16 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Orchard.Caching;
using Orchard.FileSystems.VirtualPath;
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;
public CommandHostVirtualPathMonitor(IVirtualPathProvider virtualPathProvider) {

View File

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

View File

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

View File

@@ -27,11 +27,6 @@ namespace Orchard.Environment.Descriptor {
/// Loss of storage is expected.
/// </summary>
void Store(string shellName, ShellDescriptor descriptor);
/// <summary>
/// Monitor changes on the persistent storage.
/// </summary>
void Monitor(Action<IVolatileToken> monitor);
}
public class ShellDescriptorCache : IShellDescriptorCache {
@@ -104,10 +99,6 @@ namespace Orchard.Environment.Descriptor {
_appDataFolder.CreateFile(DescriptorCacheFileName, saveWriter.ToString());
}
public void Monitor(Action<IVolatileToken> monitor) {
monitor(_appDataFolder.WhenPathChanges(DescriptorCacheFileName));
}
#endregion
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.Configuration;
using Orchard.Caching;
using Orchard.Data;
using Orchard.Environment.AutofacUtil;
using Orchard.Environment.Configuration;
using Orchard.Environment.Extensions;
@@ -36,6 +35,7 @@ namespace Orchard.Environment {
builder.RegisterType<DefaultOrchardEventBus>().As<IEventBus>().SingleInstance();
builder.RegisterType<DefaultCacheHolder>().As<ICacheHolder>().SingleInstance();
builder.RegisterType<DefaultHostEnvironment>().As<IHostEnvironment>().SingleInstance();
builder.RegisterType<DefaultHostLocalRestart>().As<IHostLocalRestart>().SingleInstance();
builder.RegisterType<DefaultBuildManager>().As<IBuildManager>().SingleInstance();
builder.RegisterType<WebFormVirtualPathProvider>().As<ICustomVirtualPathProvider>().SingleInstance();
builder.RegisterType<DynamicModuleVirtualPathProvider>().As<ICustomVirtualPathProvider>().SingleInstance();
@@ -63,6 +63,7 @@ namespace Orchard.Environment {
.As<ICompositionStrategy>()
.SingleInstance();
{
builder.RegisterType<ShellContainerRegistrations>().As<IShellContainerRegistrations>().SingleInstance();
builder.RegisterType<ExtensionLoaderCoordinator>().As<IExtensionLoaderCoordinator>().SingleInstance();
builder.RegisterType<ExtensionManager>().As<IExtensionManager>().SingleInstance();
{

View File

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

View File

@@ -3,7 +3,7 @@ using System.Collections.Generic;
using Orchard.ContentManagement;
namespace Orchard.Indexing {
public interface IIndexProvider : IDependency {
public interface IIndexProvider : ISingletonDependency {
/// <summary>
/// Creates a new index
/// </summary>
@@ -62,7 +62,7 @@ namespace Orchard.Indexing {
ISearchBuilder CreateSearchBuilder(string indexName);
/// <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>
DateTime? GetLastIndexUtc(string indexName);

View File

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

View File

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

View File

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

View File

@@ -72,7 +72,7 @@
</ItemGroup>
<ItemGroup>
<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\AtomItemResult.cs" />
<Compile Include="Controllers\Artifacts\ContentTypeAttribute.cs" />

View File

@@ -7,7 +7,7 @@
<asp:Content ID="loginContent" ContentPlaceHolderID="MainContent" runat="server">
<h2>Log On</h2>
<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>
<% using (Html.BeginForm()) { %>