diff --git a/src/Orchard.Specs/Hosting/Orchard.Web/Config/Diagnostics.config b/src/Orchard.Specs/Hosting/Orchard.Web/Config/Diagnostics.config index a44c108d4..e3bc6cb6f 100644 --- a/src/Orchard.Specs/Hosting/Orchard.Web/Config/Diagnostics.config +++ b/src/Orchard.Specs/Hosting/Orchard.Web/Config/Diagnostics.config @@ -21,7 +21,7 @@ - + diff --git a/src/Orchard.Web/Config/Diagnostics.config b/src/Orchard.Web/Config/Diagnostics.config index 124536a7d..ee34eaabf 100644 --- a/src/Orchard.Web/Config/Diagnostics.config +++ b/src/Orchard.Web/Config/Diagnostics.config @@ -1,7 +1,7 @@  - + diff --git a/src/Orchard.Web/Modules/Orchard.Indexing/Orchard.Indexing.csproj b/src/Orchard.Web/Modules/Orchard.Indexing/Orchard.Indexing.csproj index 179e2bb84..f2d43e5c2 100644 --- a/src/Orchard.Web/Modules/Orchard.Indexing/Orchard.Indexing.csproj +++ b/src/Orchard.Web/Modules/Orchard.Indexing/Orchard.Indexing.csproj @@ -56,6 +56,7 @@ + @@ -77,6 +78,8 @@ + + diff --git a/src/Orchard.Web/Modules/Orchard.Indexing/Services/IndexingTaskExecutor.cs b/src/Orchard.Web/Modules/Orchard.Indexing/Services/IndexingTaskExecutor.cs index 27e48f6bd..2bc384b61 100644 --- a/src/Orchard.Web/Modules/Orchard.Indexing/Services/IndexingTaskExecutor.cs +++ b/src/Orchard.Web/Modules/Orchard.Indexing/Services/IndexingTaskExecutor.cs @@ -5,6 +5,7 @@ using JetBrains.Annotations; using Orchard.ContentManagement; using Orchard.Data; using Orchard.Indexing.Models; +using Orchard.Indexing.Settings; using Orchard.Logging; using Orchard.Services; using Orchard.Tasks.Indexing; @@ -23,7 +24,7 @@ namespace Orchard.Indexing.Services { private readonly IContentManager _contentManager; private readonly IIndexSynLock _indexSynLock; private const string SearchIndexName = "Search"; - + public IndexingTaskExecutor( IClock clock, IRepository repository, @@ -45,7 +46,7 @@ namespace Orchard.Indexing.Services { public void UpdateIndex(string indexName) { var synLock = _indexSynLock.GetSynLock(SearchIndexName); - if ( !System.Threading.Monitor.TryEnter(synLock) ) { + if (!System.Threading.Monitor.TryEnter(synLock)) { Logger.Information("Index was requested but was already running"); return; } @@ -70,10 +71,15 @@ namespace Orchard.Indexing.Services { // get every existing content item to index it foreach (var contentItem in _contentManager.Query(VersionOptions.Published).List()) { try { - var documentIndex = _indexProvider.New(contentItem.Id); + // skip items which are not indexed + var settings = GetTypeIndexingSettings(contentItem); + if (!settings.Included) + continue; + + var documentIndex = _indexProvider.New(contentItem.Id); _contentManager.Index(contentItem, documentIndex); - if(documentIndex.IsDirty) { + if (documentIndex.IsDirty) { updateIndexDocuments.Add(documentIndex); } } @@ -91,8 +97,10 @@ namespace Orchard.Indexing.Services { _indexProvider.SetLastIndexUtc(SearchIndexName, _clock.UtcNow); // retrieve not yet processed tasks - var taskRecords = _repository.Fetch(x => x.CreatedUtc > lastIndexing) - .ToArray(); + var taskRecords = lastIndexing == DateTime.MinValue + ? _repository.Fetch(x => true).ToArray() + : _repository.Fetch(x => x.CreatedUtc > lastIndexing).ToArray(); + // nothing to do ? if (taskRecords.Length + updateIndexDocuments.Count == 0) @@ -116,11 +124,15 @@ namespace Orchard.Indexing.Services { foreach (var taskRecord in taskRecords.Where(t => t.Action == IndexingTaskRecord.Update)) { var task = new IndexingTask(_contentManager, taskRecord); + // skip items which are not indexed + var settings = GetTypeIndexingSettings(task.ContentItem); + if (!settings.Included) + continue; + try { var documentIndex = _indexProvider.New(task.ContentItem.Id); - _contentManager.Index(task.ContentItem, documentIndex); - if ( documentIndex.IsDirty ) { + if (documentIndex.IsDirty) { updateIndexDocuments.Add(documentIndex); } @@ -143,5 +155,14 @@ namespace Orchard.Indexing.Services { System.Threading.Monitor.Exit(synLock); } } + + static TypeIndexing GetTypeIndexingSettings(ContentItem contentItem) { + if (contentItem == null || + contentItem.TypeDefinition == null || + contentItem.TypeDefinition.Settings == null) { + return new TypeIndexing { Included = false }; + } + return contentItem.TypeDefinition.Settings.GetModel(); + } } } diff --git a/src/Orchard.Web/Modules/Orchard.Indexing/Settings/ContentDefinitionEditorEvents.cs b/src/Orchard.Web/Modules/Orchard.Indexing/Settings/ContentDefinitionEditorEvents.cs new file mode 100644 index 000000000..5fd7d9cbd --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Indexing/Settings/ContentDefinitionEditorEvents.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using Orchard.ContentManagement; +using Orchard.ContentManagement.MetaData; +using Orchard.ContentManagement.MetaData.Builders; +using Orchard.ContentManagement.MetaData.Models; +using Orchard.ContentManagement.ViewModels; + +namespace Orchard.Indexing.Settings { + public class ContentDefinitionEditorEvents : ContentDefinitionEditorEventsBase { + public override IEnumerable TypeEditor(ContentTypeDefinition definition) { + var model = definition.Settings.GetModel(); + yield return DefinitionTemplate(model); + } + + public override IEnumerable TypeEditorUpdate(ContentTypeDefinitionBuilder builder, IUpdateModel updateModel) { + var model = new TypeIndexing(); + updateModel.TryUpdateModel(model, "TypeIndexing", null, null); + builder + .WithSetting("TypeIndexing.Included", model.Included ? true.ToString() : null); + + yield return DefinitionTemplate(model); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Indexing/Settings/TypeIndexing.cs b/src/Orchard.Web/Modules/Orchard.Indexing/Settings/TypeIndexing.cs new file mode 100644 index 000000000..45e90a4e7 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Indexing/Settings/TypeIndexing.cs @@ -0,0 +1,5 @@ +namespace Orchard.Indexing.Settings { + public class TypeIndexing { + public bool Included { get; set; } + } +} diff --git a/src/Orchard.Web/Modules/Orchard.Indexing/Views/DefinitionTemplates/TypeIndexing.ascx b/src/Orchard.Web/Modules/Orchard.Indexing/Views/DefinitionTemplates/TypeIndexing.ascx new file mode 100644 index 000000000..2dc8a7721 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Indexing/Views/DefinitionTemplates/TypeIndexing.ascx @@ -0,0 +1,7 @@ +<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl" %> +<%@ Import Namespace="Orchard.Mvc.Html" %> +
+ <%:Html.EditorFor(m=>m.Included) %> + + <%:Html.ValidationMessageFor(m=>m.Included) %> +
diff --git a/src/Orchard.Web/Modules/Orchard.Setup/SetupMode.cs b/src/Orchard.Web/Modules/Orchard.Setup/SetupMode.cs index 4c27ad19d..4f763a9cb 100644 --- a/src/Orchard.Web/Modules/Orchard.Setup/SetupMode.cs +++ b/src/Orchard.Web/Modules/Orchard.Setup/SetupMode.cs @@ -16,6 +16,7 @@ using Orchard.Mvc.Filters; using Orchard.Mvc.ModelBinders; using Orchard.Mvc.Routes; using Orchard.Mvc.ViewEngines; +using Orchard.Mvc.ViewEngines.WebForms; using Orchard.Settings; using Orchard.Setup.Commands; using Orchard.Themes; @@ -33,7 +34,7 @@ namespace Orchard.Setup { builder.RegisterModule(new CommandModule()); builder.RegisterType().As().InstancePerLifetimeScope(); builder.RegisterType().As().InstancePerLifetimeScope(); - builder.RegisterType().As().InstancePerLifetimeScope(); + builder.RegisterType().As().InstancePerLifetimeScope(); builder.RegisterType().As().InstancePerLifetimeScope(); builder.RegisterType().As().InstancePerLifetimeScope(); builder.RegisterType().As().InstancePerLifetimeScope(); diff --git a/src/Orchard/Environment/DefaultOrchardShell.cs b/src/Orchard/Environment/DefaultOrchardShell.cs index c4b30cb8c..2a09c992c 100644 --- a/src/Orchard/Environment/DefaultOrchardShell.cs +++ b/src/Orchard/Environment/DefaultOrchardShell.cs @@ -41,7 +41,7 @@ namespace Orchard.Environment { _routePublisher.Publish(_routeProviders.SelectMany(provider => provider.GetRoutes())); _modelBinderPublisher.Publish(_modelBinderProviders.SelectMany(provider => provider.GetModelBinders())); - AddOrchardLocationsFormats(); + //AddOrchardLocationsFormats(); using (var events = _eventsFactory()) { events.Value.Activated(); diff --git a/src/Orchard/Mvc/ViewEngines/LayoutViewEngine.cs b/src/Orchard/Mvc/ViewEngines/LayoutViewEngine.cs index 8ce81a97e..de6401aa6 100644 --- a/src/Orchard/Mvc/ViewEngines/LayoutViewEngine.cs +++ b/src/Orchard/Mvc/ViewEngines/LayoutViewEngine.cs @@ -31,7 +31,6 @@ namespace Orchard.Mvc.ViewEngines { if (skipLayoutViewEngine) return new ViewEngineResult(Enumerable.Empty()); - var bodyView = _viewEngines.FindPartialView(controllerContext, viewName); ViewEngineResult layoutView = null; @@ -109,7 +108,6 @@ namespace Orchard.Mvc.ViewEngines { return new ViewEngineResult(Enumerable.Empty()); } - public ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) { var scope = Scope.From(controllerContext); if (scope != null && scope.LayoutViewEngine != null) { @@ -120,10 +118,7 @@ namespace Orchard.Mvc.ViewEngines { return new ViewEngineResult(Enumerable.Empty()); } - - public void ReleaseView(ControllerContext controllerContext, IView view) { - throw new NotImplementedException(); } } diff --git a/src/Orchard/Mvc/ViewEngines/ViewEngineFilter.cs b/src/Orchard/Mvc/ViewEngines/ViewEngineFilter.cs index 832eec526..c1fd4b19b 100644 --- a/src/Orchard/Mvc/ViewEngines/ViewEngineFilter.cs +++ b/src/Orchard/Mvc/ViewEngines/ViewEngineFilter.cs @@ -63,7 +63,7 @@ namespace Orchard.Mvc.ViewEngines { var requestViewEngines = new ViewEngineCollection( themeViewEngines .Concat(moduleViewEngines) - .Concat(_viewEngines.Where(x => x.GetType().Assembly != typeof(LayoutViewEngine).Assembly)) + .Concat(_viewEngines.Where(ViewEngineIsForwarded)) .ToArray()); var layoutViewEngine = new LayoutViewEngine(requestViewEngines); @@ -72,6 +72,14 @@ namespace Orchard.Mvc.ViewEngines { viewResultBase.ViewEngineCollection.Insert(0, layoutViewEngine); } + static bool ViewEngineIsForwarded(IViewEngine x) { + // default view engine, and layout view engine, are not forwarded to + // be used for resolving partials + return + x.GetType().Assembly != typeof(LayoutViewEngine).Assembly && + x.GetType() != typeof(WebFormViewEngine); + } + public void OnResultExecuted(ResultExecutedContext filterContext) { } diff --git a/src/Orchard/Mvc/ViewEngines/ThemeViewLocationCache.cs b/src/Orchard/Mvc/ViewEngines/WebForms/ThemeViewLocationCache.cs similarity index 88% rename from src/Orchard/Mvc/ViewEngines/ThemeViewLocationCache.cs rename to src/Orchard/Mvc/ViewEngines/WebForms/ThemeViewLocationCache.cs index a5a39f1eb..16e4e76c4 100644 --- a/src/Orchard/Mvc/ViewEngines/ThemeViewLocationCache.cs +++ b/src/Orchard/Mvc/ViewEngines/WebForms/ThemeViewLocationCache.cs @@ -1,13 +1,10 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Web.Mvc; using System.Web.Caching; using System.Web; using System.Web.Hosting; -namespace Orchard.Mvc.ViewEngines { +namespace Orchard.Mvc.ViewEngines.WebForms { public class ThemeViewLocationCache : IViewLocationCache { private readonly string _requestTheme; diff --git a/src/Orchard/Mvc/ViewEngines/WebForms/WebFormViewEngineForAspNet4.cs b/src/Orchard/Mvc/ViewEngines/WebForms/WebFormViewEngineForAspNet4.cs new file mode 100644 index 000000000..1af79428f --- /dev/null +++ b/src/Orchard/Mvc/ViewEngines/WebForms/WebFormViewEngineForAspNet4.cs @@ -0,0 +1,25 @@ +using System.Web; +using System.Web.Compilation; +using System.Web.Mvc; + +namespace Orchard.Mvc.ViewEngines.WebForms { + public class WebFormViewEngineForAspNet4 : WebFormViewEngine { + protected override bool FileExists(ControllerContext controllerContext, string virtualPath) { + try { + + return BuildManager.GetObjectFactory(virtualPath, false) != null; + } + catch (HttpException exception) { + // Reproducing base class behavior, however these this code path should + // not be followed for "not found" cases + if (exception is HttpParseException) { + throw; + } + if ((exception.GetHttpCode() != 0x194) || base.FileExists(controllerContext, virtualPath)) { + throw; + } + return false; + } + } + } +} diff --git a/src/Orchard/Mvc/ViewEngines/WebFormsViewEngineProvider.cs b/src/Orchard/Mvc/ViewEngines/WebForms/WebFormViewEngineProvider.cs similarity index 71% rename from src/Orchard/Mvc/ViewEngines/WebFormsViewEngineProvider.cs rename to src/Orchard/Mvc/ViewEngines/WebForms/WebFormViewEngineProvider.cs index 6192160fb..28c69eb0c 100644 --- a/src/Orchard/Mvc/ViewEngines/WebFormsViewEngineProvider.cs +++ b/src/Orchard/Mvc/ViewEngines/WebForms/WebFormViewEngineProvider.cs @@ -2,9 +2,9 @@ using System.Web.Mvc; using Orchard.Logging; -namespace Orchard.Mvc.ViewEngines { - public class WebFormsViewEngineProvider : IViewEngineProvider { - public WebFormsViewEngineProvider() { +namespace Orchard.Mvc.ViewEngines.WebForms { + public class WebFormViewEngineProvider : IViewEngineProvider { + public WebFormViewEngineProvider() { Logger = NullLogger.Instance; } static string[] DisabledFormats = new[] { "~/Disabled" }; @@ -22,35 +22,35 @@ namespace Orchard.Mvc.ViewEngines { // Partial Paths - // {area}/{controller}/ - - var viewEngine = new WebFormViewEngine { - MasterLocationFormats = DisabledFormats, - ViewLocationFormats = DisabledFormats, - AreaMasterLocationFormats = DisabledFormats, - AreaViewLocationFormats = DisabledFormats, - AreaPartialViewLocationFormats = DisabledFormats, - }; - - viewEngine.ViewLocationCache = new ThemeViewLocationCache(parameters.VirtualPath); + // for "routed" request views... + // enable /Views/{area}/{controller}/{viewName} // enable /Views/{partialName} // enable /Views/"DisplayTemplates/"+{templateName} // enable /Views/"EditorTemplates/+{templateName} - viewEngine.PartialViewLocationFormats = new[] { + var partialViewLocationFormats = new[] { parameters.VirtualPath + "/Views/{0}.ascx", parameters.VirtualPath + "/Views/{0}.aspx", }; - Logger.Debug("PartialViewLocationFormats (theme): \r\n\t-{0}", string.Join("\r\n\t-", viewEngine.PartialViewLocationFormats)); + //Logger.Debug("PartialViewLocationFormats (theme): \r\n\t-{0}", string.Join("\r\n\t-", partialViewLocationFormats)); - // for "routed" request views... - // enable /Views/{area}/{controller}/{viewName} - viewEngine.AreaPartialViewLocationFormats = new[] { + var areaPartialViewLocationFormats = new[] { parameters.VirtualPath + "/Views/{2}/{1}/{0}.ascx", parameters.VirtualPath + "/Views/{2}/{1}/{0}.aspx", }; - Logger.Debug("AreaPartialViewLocationFormats (theme): \r\n\t-{0}", string.Join("\r\n\t-", viewEngine.AreaPartialViewLocationFormats)); + //Logger.Debug("AreaPartialViewLocationFormats (theme): \r\n\t-{0}", string.Join("\r\n\t-", areaPartialViewLocationFormats)); + + var viewEngine = new WebFormViewEngineForAspNet4 { + MasterLocationFormats = DisabledFormats, + ViewLocationFormats = DisabledFormats, + PartialViewLocationFormats = partialViewLocationFormats, + AreaMasterLocationFormats = DisabledFormats, + AreaViewLocationFormats = DisabledFormats, + AreaPartialViewLocationFormats = areaPartialViewLocationFormats, + ViewLocationCache = new ThemeViewLocationCache(parameters.VirtualPath), + }; return viewEngine; } @@ -63,7 +63,7 @@ namespace Orchard.Mvc.ViewEngines { "~/Modules/{2}/Views/{1}/{0}.aspx", }; - Logger.Debug("AreaFormats (module): \r\n\t-{0}", string.Join("\r\n\t-", areaFormats)); + //Logger.Debug("AreaFormats (module): \r\n\t-{0}", string.Join("\r\n\t-", areaFormats)); var universalFormats = parameters.VirtualPaths .SelectMany(x => new[] { @@ -72,9 +72,9 @@ namespace Orchard.Mvc.ViewEngines { }) .ToArray(); - Logger.Debug("UniversalFormats (module): \r\n\t-{0}", string.Join("\r\n\t-", universalFormats)); + //Logger.Debug("UniversalFormats (module): \r\n\t-{0}", string.Join("\r\n\t-", universalFormats)); - var viewEngine = new WebFormViewEngine { + var viewEngine = new WebFormViewEngineForAspNet4 { MasterLocationFormats = DisabledFormats, ViewLocationFormats = universalFormats, PartialViewLocationFormats = universalFormats, diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index 2edd3eaaf..e8355d76c 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -463,6 +463,7 @@ + @@ -557,7 +558,7 @@ - + ASPXCodeBehind @@ -644,7 +645,7 @@ - +