mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Merge
--HG-- branch : dev
This commit is contained in:
@@ -293,6 +293,8 @@
|
||||
DestinationFolder="$(MsDeployFolder)\Orchard\%(RecursiveDir)"/>
|
||||
<Copy SourceFiles="@(MsDeploy-Parameters)"
|
||||
DestinationFolder="$(MsDeployFolder)"/>
|
||||
|
||||
<MakeDir Directories="$(MsDeployFolder)\Orchard\bin\HostRestart"/>
|
||||
</Target>
|
||||
|
||||
<Target Name="Package-Zip">
|
||||
|
@@ -2,5 +2,6 @@
|
||||
<iisapp path="Orchard" managedRuntimeVersion="v4.0" />
|
||||
<setAcl path="Orchard/App_Data" setAclAccess="Modify" />
|
||||
<setAcl path="Orchard/Media" setAclAccess="Modify" />
|
||||
<setAcl path="Orchard/bin/HostRestart" setAclAccess="Modify" />
|
||||
<dbFullSql path="install.sql" />
|
||||
</MSDeploy.iisApp>
|
||||
|
@@ -13,6 +13,10 @@
|
||||
<parameterEntry type="ProviderPath" scope="setAcl" match="Orchard/Media" />
|
||||
</parameter>
|
||||
|
||||
<parameter name="SetAclParameter3" description="Hidden - automatically sets write access for the app" defaultValue="{Application Path}/bin/HostRestart" tags="Hidden">
|
||||
<parameterEntry type="ProviderPath" scope="setAcl" match="Orchard/bin/HostRestart" />
|
||||
</parameter>
|
||||
|
||||
<!-- Prompts for database server name, this is used in the connection string parameter later -->
|
||||
<parameter name="Database Server" description="Location of your database server (i.e. server name, IP address, or server\instance)" defaultValue=".\SQLEXPRESS" tags="SQL, dbServer">
|
||||
</parameter>
|
||||
|
@@ -4,7 +4,7 @@ using Orchard.Environment.Warmup;
|
||||
|
||||
namespace Orchard.Tests.Environment.Warmup {
|
||||
[TestFixture]
|
||||
public class WarmUpUtilityTests {
|
||||
public class WarmupUtilityTests {
|
||||
|
||||
[Test]
|
||||
public void EmptyStringsAreNotAllowed() {
|
||||
|
@@ -240,7 +240,7 @@
|
||||
<Compile Include="Environment\RunningShellTableTests.cs" />
|
||||
<Compile Include="Environment\StubHostEnvironment.cs" />
|
||||
<Compile Include="Environment\Utility\Build.cs" />
|
||||
<Compile Include="Environment\WarmUp\WarmUpUtilityTests.cs" />
|
||||
<Compile Include="Environment\Warmup\WarmupUtilityTests.cs" />
|
||||
<Compile Include="FileSystems\AppData\AppDataFolderTests.cs" />
|
||||
<Compile Include="Environment\Configuration\DefaultTenantManagerTests.cs" />
|
||||
<Compile Include="Environment\DefaultCompositionStrategyTests.cs" />
|
||||
|
@@ -1,22 +1,18 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using Autofac;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Environment.Warmup;
|
||||
using Orchard.Utility.Extensions;
|
||||
|
||||
namespace Orchard.Web {
|
||||
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
|
||||
// visit http://go.microsoft.com/?LinkId=9394801
|
||||
|
||||
public class MvcApplication : HttpApplication {
|
||||
private static StartupResult _startupResult;
|
||||
private static EventWaitHandle _waitHandle;
|
||||
private static IOrchardHost _host;
|
||||
private static Exception _error;
|
||||
|
||||
public static void RegisterRoutes(RouteCollection routes) {
|
||||
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
|
||||
@@ -26,77 +22,30 @@ namespace Orchard.Web {
|
||||
LaunchStartupThread();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes Orchard's Host in a separate thread
|
||||
/// </summary>
|
||||
private static void LaunchStartupThread() {
|
||||
_startupResult = new StartupResult();
|
||||
_waitHandle = new AutoResetEvent(false);
|
||||
|
||||
ThreadPool.QueueUserWorkItem(
|
||||
state => {
|
||||
try {
|
||||
RegisterRoutes(RouteTable.Routes);
|
||||
var host = OrchardStarter.CreateHost(MvcSingletons);
|
||||
host.Initialize();
|
||||
_startupResult.Host = host;
|
||||
}
|
||||
catch (Exception e) {
|
||||
_startupResult.Error = e;
|
||||
}
|
||||
finally {
|
||||
_waitHandle.Set();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void Application_BeginRequest() {
|
||||
// Host is still starting up?
|
||||
if (_startupResult.Host == null && _startupResult.Error == null) {
|
||||
if (_error != null) {
|
||||
// Host startup resulted in an error
|
||||
|
||||
// use the url as it was requested by the client
|
||||
// the real url might be different if it has been translated (proxy, load balancing, ...)
|
||||
var url = Request.ToUrlString();
|
||||
var virtualFileCopy = "~/App_Data/WarmUp/" + WarmupUtility.EncodeUrl(url.Trim('/'));
|
||||
var localCopy = HostingEnvironment.MapPath(virtualFileCopy);
|
||||
|
||||
if (File.Exists(localCopy)) {
|
||||
// result should not be cached, even on proxies
|
||||
Context.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
|
||||
Context.Response.Cache.SetValidUntilExpires(false);
|
||||
Context.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
|
||||
Context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
|
||||
Context.Response.Cache.SetNoStore();
|
||||
|
||||
Context.Response.WriteFile(localCopy);
|
||||
Context.Response.End();
|
||||
}
|
||||
else if(!File.Exists(Request.PhysicalPath)) {
|
||||
// there is no local copy and the host is not running
|
||||
// wait for the host to initialize
|
||||
_waitHandle.WaitOne();
|
||||
}
|
||||
// Throw error once, and restart launch; machine state may have changed
|
||||
// so we need to simulate a "restart".
|
||||
var error = _error;
|
||||
LaunchStartupThread();
|
||||
throw error;
|
||||
}
|
||||
else {
|
||||
if (_startupResult.Error != null) {
|
||||
// Host startup resulted in an error
|
||||
|
||||
// Throw error once, and restart launch (machine state may have changed
|
||||
// so we need to simulate a "restart".
|
||||
var error = _startupResult.Error;
|
||||
LaunchStartupThread();
|
||||
throw error;
|
||||
}
|
||||
|
||||
Context.Items["originalHttpContext"] = Context;
|
||||
_startupResult.Host.BeginRequest();
|
||||
// Only notify if the host has started up
|
||||
if (_host == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Context.Items["originalHttpContext"] = Context;
|
||||
_host.BeginRequest();
|
||||
}
|
||||
|
||||
protected void Application_EndRequest() {
|
||||
// Only notify if the host has started up
|
||||
if (_startupResult.Host != null) {
|
||||
_startupResult.Host.EndRequest();
|
||||
if (_host != null) {
|
||||
_host.EndRequest();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,5 +54,31 @@ namespace Orchard.Web {
|
||||
builder.Register(ctx => ModelBinders.Binders).SingleInstance();
|
||||
builder.Register(ctx => ViewEngines.Engines).SingleInstance();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes Orchard's Host in a separate thread
|
||||
/// </summary>
|
||||
private static void LaunchStartupThread() {
|
||||
RegisterRoutes(RouteTable.Routes);
|
||||
|
||||
_host = null;
|
||||
_error = null;
|
||||
|
||||
ThreadPool.QueueUserWorkItem(
|
||||
state => {
|
||||
try {
|
||||
var host = OrchardStarter.CreateHost(MvcSingletons);
|
||||
host.Initialize();
|
||||
_host = host;
|
||||
}
|
||||
catch (Exception e) {
|
||||
_error = e;
|
||||
}
|
||||
finally {
|
||||
// Execute pending actions as the host is available
|
||||
WarmupHttpModule.Signal();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
35
src/Orchard.Web/Modules/Orchard.Experimental/LockLogging.cs
Normal file
35
src/Orchard.Web/Modules/Orchard.Experimental/LockLogging.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.Data;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Logging;
|
||||
using Orchard.Mvc.Filters;
|
||||
|
||||
namespace Orchard.Experimental {
|
||||
[OrchardFeature("Orchard.Experimental.LockLogging")]
|
||||
public class LockLogging : FilterProvider, IExceptionFilter {
|
||||
private readonly Work<ISessionLocator> _sessionLocator;
|
||||
private readonly ITransactionManager _transactionManager;
|
||||
|
||||
public LockLogging(Work<ISessionLocator> sessionLocator) {
|
||||
_sessionLocator = sessionLocator;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public void OnException(ExceptionContext filterContext) {
|
||||
var connection = _sessionLocator.Value.For(null).Connection;
|
||||
var command = connection.CreateCommand();
|
||||
command.CommandText = "SELECT * FROM sys.lock_information";
|
||||
var reader = command.ExecuteReader();
|
||||
while (reader.Read()) {
|
||||
var fields = Enumerable.Range(0, reader.FieldCount)
|
||||
.Select(i => new { Key = reader.GetName(i), Value = reader.GetValue(i) });
|
||||
var message = fields.Aggregate("sys.lock_information", (sz, kv) => sz + " " + kv.Key + ":" + kv.Value);
|
||||
Logger.Debug(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -21,3 +21,7 @@ Features:
|
||||
Description: Adds some content definitions to help test lists
|
||||
Dependencies: Orchard.Lists
|
||||
Category: Developer
|
||||
Orchard.Experimental.LockLogging:
|
||||
Name: Lock Logging
|
||||
Description: Logs extra diagnostic information for Sql CE if a deadlock timeout occurs
|
||||
Category: Developer
|
||||
|
@@ -39,10 +39,12 @@
|
||||
<HintPath>..\..\..\..\lib\autofac\Autofac.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="NHibernate, Version=2.1.2.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\lib\aspnetmvc\System.Web.Mvc.dll</HintPath>
|
||||
@@ -62,6 +64,7 @@
|
||||
<Compile Include="Controllers\MetadataController.cs" />
|
||||
<Compile Include="DebugFilter.cs" />
|
||||
<Compile Include="Handlers\DebugLinkHandler.cs" />
|
||||
<Compile Include="LockLogging.cs" />
|
||||
<Compile Include="Migrations.cs" />
|
||||
<Compile Include="Models\ShowDebugLink.cs" />
|
||||
<Compile Include="Models\Simple.cs" />
|
||||
|
@@ -60,47 +60,26 @@ namespace Lists.Controllers {
|
||||
public ActionResult List(ListContentsViewModel model, PagerParameters pagerParameters) {
|
||||
var pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
|
||||
var container = model.ContainerId.HasValue ? _contentManager.GetLatest((int)model.ContainerId) : null;
|
||||
if (container == null && model.ContainerId.HasValue) {
|
||||
if (container == null || !container.Has<ContainerPart>()) {
|
||||
return HttpNotFound();
|
||||
}
|
||||
var restrictedContentType = container == null ? null : container.As<ContainerPart>().Record.ItemContentType;
|
||||
var restrictedContentType = container.As<ContainerPart>().Record.ItemContentType;
|
||||
var hasRestriction = !string.IsNullOrEmpty(restrictedContentType);
|
||||
if (hasRestriction) {
|
||||
model.FilterByContentType = restrictedContentType;
|
||||
}
|
||||
|
||||
if (container != null) {
|
||||
var metadata = container.ContentManager.GetItemMetadata(container);
|
||||
model.ContainerDisplayName = metadata.DisplayText;
|
||||
if (string.IsNullOrEmpty(model.ContainerDisplayName)) {
|
||||
model.ContainerDisplayName = container.ContentType;
|
||||
}
|
||||
}
|
||||
|
||||
var query = _contentManager.Query<ContainablePart>(VersionOptions.Latest);
|
||||
|
||||
if (!string.IsNullOrEmpty(model.FilterByContentType)) {
|
||||
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(model.FilterByContentType);
|
||||
if (contentTypeDefinition == null)
|
||||
return HttpNotFound();
|
||||
query = query.ForType(model.FilterByContentType);
|
||||
}
|
||||
query = query.Join<CommonPartRecord>().Where(cr => cr.Container.Id == model.ContainerId);
|
||||
|
||||
switch (model.Options.OrderBy) {
|
||||
case ContentsOrder.Modified:
|
||||
query = query.OrderByDescending<CommonPartRecord, DateTime?>(cr => cr.ModifiedUtc);
|
||||
break;
|
||||
case ContentsOrder.Published:
|
||||
query = query.OrderByDescending<CommonPartRecord, DateTime?>(cr => cr.PublishedUtc);
|
||||
break;
|
||||
case ContentsOrder.Created:
|
||||
query = query.OrderByDescending<CommonPartRecord, DateTime?>(cr => cr.CreatedUtc);
|
||||
break;
|
||||
}
|
||||
|
||||
model.Options.SelectedFilter = model.FilterByContentType;
|
||||
|
||||
model.ContainerDisplayName = container.ContentManager.GetItemMetadata(container).DisplayText;
|
||||
if (string.IsNullOrEmpty(model.ContainerDisplayName)) {
|
||||
model.ContainerDisplayName = container.ContentType;
|
||||
}
|
||||
|
||||
var query = GetListContentItemQuery(model);
|
||||
if (query == null) {
|
||||
return new HttpNotFoundResult();
|
||||
}
|
||||
|
||||
if (!hasRestriction) {
|
||||
model.Options.FilterOptions = GetContainableTypes()
|
||||
.Select(ctd => new KeyValuePair<string, string>(ctd.Name, ctd.DisplayName))
|
||||
@@ -120,7 +99,7 @@ namespace Lists.Controllers {
|
||||
.Options(model.Options)
|
||||
.HasRestriction(hasRestriction)
|
||||
.ContainerDisplayName(model.ContainerDisplayName)
|
||||
.ContainerContentType(container == null ? null : container.ContentType)
|
||||
.ContainerContentType(container.ContentType)
|
||||
.ContainerItemContentType(hasRestriction ? restrictedContentType : (model.FilterByContentType ?? ""))
|
||||
.OtherLists(_contentManager.Query<ContainerPart>(VersionOptions.Latest).List()
|
||||
.Select(part => part.ContentItem)
|
||||
@@ -131,6 +110,32 @@ namespace Lists.Controllers {
|
||||
return View((object)viewModel);
|
||||
}
|
||||
|
||||
private IContentQuery<ContainablePart> GetListContentItemQuery(ListContentsViewModel model) {
|
||||
var query = _contentManager.Query<ContainablePart>(VersionOptions.Latest);
|
||||
|
||||
if (!string.IsNullOrEmpty(model.FilterByContentType)) {
|
||||
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(model.FilterByContentType);
|
||||
if (contentTypeDefinition == null) {
|
||||
return null;
|
||||
}
|
||||
query = query.ForType(model.FilterByContentType);
|
||||
}
|
||||
query = query.Join<CommonPartRecord>().Where(cr => cr.Container.Id == model.ContainerId);
|
||||
|
||||
switch (model.Options.OrderBy) {
|
||||
case ContentsOrder.Modified:
|
||||
query = query.OrderByDescending<CommonPartRecord, DateTime?>(cr => cr.ModifiedUtc);
|
||||
break;
|
||||
case ContentsOrder.Published:
|
||||
query = query.OrderByDescending<CommonPartRecord, DateTime?>(cr => cr.PublishedUtc);
|
||||
break;
|
||||
case ContentsOrder.Created:
|
||||
query = query.OrderByDescending<CommonPartRecord, DateTime?>(cr => cr.CreatedUtc);
|
||||
break;
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("List")]
|
||||
[FormValueRequired("submit.BulkEdit")]
|
||||
public ActionResult ListPOST(ContentOptions options, IEnumerable<int> itemIds, int? targetContainerId, string returnUrl) {
|
||||
@@ -172,6 +177,119 @@ namespace Lists.Controllers {
|
||||
return this.RedirectLocal(returnUrl, () => RedirectToAction("List"));
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("List")]
|
||||
[FormValueRequired("submit.Filter")]
|
||||
public ActionResult ListFilterPOST(ContentOptions options) {
|
||||
var routeValues = ControllerContext.RouteData.Values;
|
||||
if (options != null) {
|
||||
routeValues["Options.OrderBy"] = options.OrderBy;
|
||||
if (GetContainableTypes().Any(ctd => string.Equals(ctd.Name, options.SelectedFilter, StringComparison.OrdinalIgnoreCase))) {
|
||||
routeValues["filterByContentType"] = options.SelectedFilter;
|
||||
}
|
||||
else {
|
||||
routeValues.Remove("filterByContentType");
|
||||
}
|
||||
}
|
||||
|
||||
return RedirectToAction("List", routeValues);
|
||||
}
|
||||
|
||||
public ActionResult Choose(ChooseContentsViewModel model, PagerParameters pagerParameters) {
|
||||
var pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
|
||||
var container = model.SourceContainerId == 0 ? null : _contentManager.GetLatest(model.SourceContainerId);
|
||||
if (container == null && model.SourceContainerId != 0) {
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
var query = _contentManager.Query<ContainablePart>(VersionOptions.Latest);
|
||||
|
||||
if (!string.IsNullOrEmpty(model.FilterByContentType)) {
|
||||
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(model.FilterByContentType);
|
||||
if (contentTypeDefinition == null) {
|
||||
return HttpNotFound();
|
||||
}
|
||||
query = query.ForType(model.FilterByContentType);
|
||||
}
|
||||
if (model.SourceContainerId == 0) {
|
||||
query = query.Join<CommonPartRecord>().Where(cr => cr.Container == null);
|
||||
}
|
||||
else {
|
||||
query = query.Join<CommonPartRecord>().Where(cr => cr.Container.Id == model.SourceContainerId);
|
||||
}
|
||||
|
||||
switch (model.OrderBy) {
|
||||
case ContentsOrder.Modified:
|
||||
query = query.OrderByDescending<CommonPartRecord, DateTime?>(cr => cr.ModifiedUtc);
|
||||
break;
|
||||
case ContentsOrder.Published:
|
||||
query = query.OrderByDescending<CommonPartRecord, DateTime?>(cr => cr.PublishedUtc);
|
||||
break;
|
||||
case ContentsOrder.Created:
|
||||
query = query.OrderByDescending<CommonPartRecord, DateTime?>(cr => cr.CreatedUtc);
|
||||
break;
|
||||
}
|
||||
|
||||
model.SelectedFilter = model.FilterByContentType;
|
||||
|
||||
model.FilterOptions = GetContainableTypes()
|
||||
.Select(ctd => new KeyValuePair<string, string>(ctd.Name, ctd.DisplayName))
|
||||
.ToList().OrderBy(kvp => kvp.Key);
|
||||
|
||||
var pagerShape = Shape.Pager(pager).TotalItemCount(query.Count());
|
||||
var pageOfContentItems = query.Slice(pager.GetStartIndex(), pager.PageSize).ToList();
|
||||
|
||||
var list = Shape.List();
|
||||
list.AddRange(pageOfContentItems.Select(ci => _contentManager.BuildDisplay(ci, "SummaryAdmin")));
|
||||
|
||||
dynamic viewModel = Shape.ViewModel()
|
||||
.ContentItems(list)
|
||||
.Pager(pagerShape)
|
||||
.SourceContainerId(model.SourceContainerId)
|
||||
.TargetContainerId(model.TargetContainerId)
|
||||
.SelectedFilter(model.SelectedFilter)
|
||||
.FilterOptions(model.FilterOptions)
|
||||
.OrderBy(model.OrderBy)
|
||||
.Containers(_contentManager.Query<ContainerPart>(VersionOptions.Latest).List()
|
||||
.Select(part => part.ContentItem)
|
||||
.OrderBy(item => item.As<CommonPart>().VersionPublishedUtc));
|
||||
|
||||
// Casting to avoid invalid (under medium trust) reflection over the protected View method and force a static invocation.
|
||||
return View((object)viewModel);
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("Choose")]
|
||||
[FormValueRequired("submit.MoveTo")]
|
||||
public ActionResult ChoosePOST(IEnumerable<int> itemIds, int targetContainerId, string returnUrl) {
|
||||
if (itemIds != null && !BulkMoveToList(itemIds, targetContainerId)) {
|
||||
return new HttpUnauthorizedResult();
|
||||
}
|
||||
|
||||
return this.RedirectLocal(returnUrl, () => RedirectToAction("List", new { ContainerId = targetContainerId }));
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("Choose")]
|
||||
[FormValueRequired("submit.Filter")]
|
||||
public ActionResult ChooseFilterPOST(ChooseContentsViewModel model) {
|
||||
var routeValues = ControllerContext.RouteData.Values;
|
||||
if (GetContainableTypes().Any(ctd => string.Equals(ctd.Name, model.SelectedFilter, StringComparison.OrdinalIgnoreCase))) {
|
||||
routeValues["filterByContentType"] = model.SelectedFilter;
|
||||
}
|
||||
else {
|
||||
routeValues.Remove("filterByContentType");
|
||||
}
|
||||
if (model.SourceContainerId == 0) {
|
||||
routeValues.Remove("SourceContainerId");
|
||||
}
|
||||
else {
|
||||
routeValues["SourceContainerId"] = model.SourceContainerId;
|
||||
}
|
||||
routeValues["OrderBy"] = model.OrderBy;
|
||||
routeValues["TargetContainerId"] = model.TargetContainerId;
|
||||
|
||||
return RedirectToAction("Choose", routeValues);
|
||||
}
|
||||
|
||||
|
||||
private bool BulkMoveToList(IEnumerable<int> itemIds, int? targetContainerId) {
|
||||
if (!targetContainerId.HasValue) {
|
||||
Services.Notifier.Information(T("Please select the list to move the items to."));
|
||||
@@ -248,23 +366,5 @@ namespace Lists.Controllers {
|
||||
return true;
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("List")]
|
||||
[FormValueRequired("submit.Filter")]
|
||||
public ActionResult ListFilterPOST(ContentOptions options) {
|
||||
var routeValues = ControllerContext.RouteData.Values;
|
||||
if (options != null) {
|
||||
routeValues["Options.OrderBy"] = options.OrderBy;
|
||||
if (GetContainableTypes().Any(ctd => string.Equals(ctd.Name, options.SelectedFilter, StringComparison.OrdinalIgnoreCase))) {
|
||||
routeValues["filterByContentType"] = options.SelectedFilter;
|
||||
}
|
||||
else {
|
||||
routeValues.Remove("filterByContentType");
|
||||
}
|
||||
}
|
||||
|
||||
return RedirectToAction("List", routeValues);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -52,6 +52,7 @@
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Routes.cs" />
|
||||
<Content Include="Scripts\orchard-lists-admin.js" />
|
||||
<Compile Include="ViewModels\ChooseContentsViewModel.cs" />
|
||||
<Compile Include="ViewModels\ListContentsViewModel.cs" />
|
||||
<Content Include="Module.txt" />
|
||||
</ItemGroup>
|
||||
@@ -98,6 +99,9 @@
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\Admin\Choose.cshtml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
|
@@ -24,24 +24,7 @@ namespace Orchard.Lists {
|
||||
{"filterByContentType", ""}
|
||||
},
|
||||
new RouteValueDictionary{
|
||||
{"filterByContentType", @"\w+"},
|
||||
{"containerId", @"\d+"}
|
||||
},
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Lists"}
|
||||
},
|
||||
new MvcRouteHandler())
|
||||
},
|
||||
new RouteDescriptor {
|
||||
Priority = 5,
|
||||
Route = new Route(
|
||||
"Admin/Lists/{containerId}",
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Lists"},
|
||||
{"controller", "Admin"},
|
||||
{"action", "List"}
|
||||
},
|
||||
new RouteValueDictionary {
|
||||
{"filterByContentType", @"\w*"},
|
||||
{"containerId", @"\d+"}
|
||||
},
|
||||
new RouteValueDictionary {
|
||||
@@ -53,15 +36,17 @@ namespace Orchard.Lists {
|
||||
new RouteDescriptor {
|
||||
Priority = 5,
|
||||
Route = new Route(
|
||||
"Admin/Lists/Orphaned/{filterByContentType}",
|
||||
"Admin/Lists/Choose/From/Orphaned/To/{targetContainerId}/{filterByContentType}",
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Lists"},
|
||||
{"controller", "Admin"},
|
||||
{"action", "List"},
|
||||
{"action", "Choose"},
|
||||
{"filterByContentType", ""},
|
||||
{"sourceContainerId", "0"}
|
||||
},
|
||||
new RouteValueDictionary{
|
||||
{"filterByContentType", @"\w+"},
|
||||
{"filterByContentType", @"\w*"},
|
||||
{"targetContainerId", @"\d+"},
|
||||
},
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Lists"}
|
||||
@@ -71,19 +56,23 @@ namespace Orchard.Lists {
|
||||
new RouteDescriptor {
|
||||
Priority = 5,
|
||||
Route = new Route(
|
||||
"Admin/Lists/Orphaned",
|
||||
"Admin/Lists/Choose/From/{sourceContainerId}/To/{targetContainerId}/{filterByContentType}",
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Lists"},
|
||||
{"controller", "Admin"},
|
||||
{"action", "List"},
|
||||
{"action", "Choose"},
|
||||
{"filterByContentType", ""}
|
||||
},
|
||||
new RouteValueDictionary{
|
||||
{"filterByContentType", @"\w*"},
|
||||
{"sourceContainerId", @"\d+"},
|
||||
{"targetContainerId", @"\d+"},
|
||||
},
|
||||
null,
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Lists"}
|
||||
},
|
||||
new MvcRouteHandler())
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,21 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.ContentManagement;
|
||||
|
||||
namespace Orchard.Lists.ViewModels {
|
||||
public class ChooseContentsViewModel {
|
||||
public ChooseContentsViewModel() {
|
||||
OrderBy = ContentsOrder.Modified;
|
||||
}
|
||||
|
||||
public string FilterByContentType { get; set; }
|
||||
public int SourceContainerId { get; set; }
|
||||
public int TargetContainerId { get; set; }
|
||||
|
||||
public int? Page { get; set; }
|
||||
|
||||
public string SelectedFilter { get; set; }
|
||||
public IEnumerable<KeyValuePair<string, string>> FilterOptions { get; set; }
|
||||
public ContentsOrder OrderBy { get; set; }
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
@using Orchard.Lists.ViewModels;
|
||||
@using Orchard.ContentManagement;
|
||||
@{
|
||||
var sourceContainerId = (int)Model.SourceContainerId;
|
||||
var targetContainerId = (int)Model.TargetContainerId;
|
||||
|
||||
Layout.Title = T("Choose Items");
|
||||
|
||||
var targetContainers = ((IEnumerable<ContentItem>)Model.Containers).Select(
|
||||
contentItem => new SelectListItem {
|
||||
Text = T("Move to {0}", contentItem.ContentManager.GetItemMetadata(contentItem).DisplayText).ToString(),
|
||||
Value = contentItem.Id.ToString(System.Globalization.CultureInfo.InvariantCulture),
|
||||
Selected = contentItem.Id == targetContainerId
|
||||
}).ToList();
|
||||
|
||||
var sourceContainers = ((IEnumerable<ContentItem>)Model.Containers).Select(
|
||||
contentItem => new SelectListItem {
|
||||
Text = contentItem.ContentManager.GetItemMetadata(contentItem).DisplayText,
|
||||
Value = contentItem.Id.ToString(System.Globalization.CultureInfo.InvariantCulture),
|
||||
Selected = contentItem.Id == sourceContainerId
|
||||
}).ToList();
|
||||
sourceContainers.Insert(0, new SelectListItem { Text = T("Orphan items").ToString(), Value = "" });
|
||||
}
|
||||
|
||||
@using (Html.BeginFormAntiForgeryPost()) {
|
||||
<fieldset class="bulk-actions">
|
||||
<label for="filterResults">@T("Show")</label>
|
||||
<select id="filterResults" name="SelectedFilter">
|
||||
@Html.SelectOption((string)Model.SelectedFilter, "", T("any (show all)").ToString())
|
||||
@foreach(var filterOption in Model.FilterOptions) {
|
||||
@Html.SelectOption((string)Model.SelectedFilter, (string)filterOption.Key, (string)filterOption.Value)
|
||||
}
|
||||
</select>
|
||||
|
||||
<label for="SourceContainerId">@T("from")</label>
|
||||
@Html.DropDownList("SourceContainerId", sourceContainers, new { id = "SourceContainerId" })
|
||||
|
||||
<label for="orderResults" class="bulk-order">@T("Ordered by")</label>
|
||||
<select id="orderResults" name="OrderBy">
|
||||
@Html.SelectOption((ContentsOrder)Model.OrderBy, ContentsOrder.Created, T("recently created").ToString())
|
||||
@Html.SelectOption((ContentsOrder)Model.OrderBy, ContentsOrder.Modified, T("recently modified").ToString())
|
||||
@Html.SelectOption((ContentsOrder)Model.OrderBy, ContentsOrder.Published, T("recently published").ToString())
|
||||
</select>
|
||||
|
||||
<button type="submit" name="submit.Filter" value="yes">@T("Apply")</button>
|
||||
</fieldset>
|
||||
|
||||
<div class="manage">
|
||||
@Html.DropDownList("TargetContainerId", targetContainers)
|
||||
<button type="submit" name="submit.MoveTo" value="yes">@T("Apply")</button>
|
||||
</div>
|
||||
|
||||
<fieldset class="contentItems bulk-items">
|
||||
@if ((int)Model.ContentItems.Items.Count == 0) {
|
||||
@T("There are no content items.")
|
||||
}
|
||||
else {
|
||||
@Display(Model.ContentItems)
|
||||
}
|
||||
</fieldset>
|
||||
@Display(Model.Pager)
|
||||
}
|
@@ -3,11 +3,11 @@
|
||||
@{
|
||||
Script.Include("orchard-lists-admin.js");
|
||||
|
||||
int? containerId = (int?)Model.ContainerId;
|
||||
int containerId = ((int?)Model.ContainerId).GetValueOrDefault();
|
||||
|
||||
string createLinkText = string.IsNullOrEmpty(Model.ContainerItemContentType) ? T("Create New Content").ToString() : T("Create New {0}", Model.ContainerItemContentType).ToString();
|
||||
|
||||
Layout.Title = containerId.HasValue ? T("Manage Content for {0}", Model.ContainerDisplayName) : T("Orphaned Content Items");
|
||||
Layout.Title = T("Manage Content for {0}", Model.ContainerDisplayName);
|
||||
|
||||
var lists = ((IEnumerable<ContentItem>)Model.OtherLists).Select(
|
||||
contentItem => new SelectListItem {
|
||||
@@ -24,22 +24,19 @@
|
||||
|
||||
<div> </div>
|
||||
@Display.Parts_Container_Manage(ContainerDisplayName: Model.ContainerDisplayName, ContainerContentType: Model.ContainerContentType, ContainerId: containerId)
|
||||
@if (containerId.HasValue) {
|
||||
<div class="manage">
|
||||
@Html.ActionLink(createLinkText, "Create", new { Area = "Contents", Id = (string)Model.Options.SelectedFilter, ContainerId = (int)containerId, ReturnUrl = Url.Action("List", "Admin", new { Area = "Orchard.Lists", ContainerId = (int)containerId }) }, new { @class = "button primaryAction" })
|
||||
@Html.ActionLink(createLinkText, "Create", new { Area = "Contents", Id = (string)Model.Options.SelectedFilter, ContainerId = containerId, ReturnUrl = Url.Action("List", "Admin", new { Area = "Orchard.Lists", ContainerId = containerId }) }, new { @class = "button primaryAction" })
|
||||
</div>
|
||||
}
|
||||
|
||||
@using (Html.BeginFormAntiForgeryPost()) {
|
||||
<fieldset class="bulk-actions">
|
||||
<label for="publishActions">@T("Actions:")</label>
|
||||
<select id="publishActions" name="Options.BulkAction">
|
||||
@if (containerId.HasValue) {
|
||||
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.None, T("Choose action...").ToString())
|
||||
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.PublishNow, T("Publish Now").ToString())
|
||||
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.Unpublish, T("Unpublish").ToString())
|
||||
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.Remove, T("Delete").ToString())
|
||||
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.RemoveFromList, T("Remove from List").ToString())
|
||||
}
|
||||
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.MoveToList, T("Move to List...").ToString())
|
||||
</select>
|
||||
@Html.DropDownList("TargetContainerId", lists, new { id = "TargetContainerId" })
|
||||
|
@@ -1,10 +1,7 @@
|
||||
<div class="item-properties actions">
|
||||
<p>
|
||||
@Html.ActionLink(T("Show Other Lists").ToString(), "List", new { Area = "Contents", Id = Model.ContainerContentType }) |
|
||||
@Html.ActionLink(T("Show Orphaned Content Items").ToString(), "Orphaned", new { Area = "Orchard.Lists" })
|
||||
@if (((int?)Model.ContainerId).HasValue) {
|
||||
<text>|</text>
|
||||
@Html.ActionLink(T("{0} Properties", (string)Model.ContainerContentType).ToString(), "Edit", new { Area = "Contents", Id = (int)Model.ContainerId })
|
||||
}
|
||||
@Html.ActionLink(T("Choose Items").ToString(), "Choose", new { TargetContainerId = (int)Model.ContainerId, Area = "Orchard.Lists" })
|
||||
<text>|</text>
|
||||
@Html.ActionLink(T("{0} Properties", (string)Model.ContainerContentType).ToString(), "Edit", new { Area = "Contents", Id = (int)Model.ContainerId, ReturnUrl = Html.ViewContext.HttpContext.Request.RawUrl })
|
||||
</p>
|
||||
</div>
|
@@ -127,6 +127,7 @@
|
||||
<Compile Include="Global.asax.cs">
|
||||
<DependentUpon>Global.asax</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="WarmupHttpModule.cs" />
|
||||
<Content Include="Config\log4net.config" />
|
||||
<Content Include="Config\Sample.HostComponents.config">
|
||||
<SubType>Designer</SubType>
|
||||
|
@@ -243,6 +243,7 @@ form.link button:hover, button.link:hover {
|
||||
***************************************************************/
|
||||
#header {
|
||||
height:50px;
|
||||
margin:16px 0 0 0;
|
||||
background:#f3f4f5;
|
||||
}
|
||||
#branding {
|
||||
|
170
src/Orchard.Web/WarmupHttpModule.cs
Normal file
170
src/Orchard.Web/WarmupHttpModule.cs
Normal file
@@ -0,0 +1,170 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
|
||||
namespace Orchard.Web {
|
||||
public class WarmupHttpModule : IHttpModule {
|
||||
private const string WarmupFilesPath = "~/App_Data/Warmup/";
|
||||
private HttpApplication _context;
|
||||
|
||||
public void Init(HttpApplication context) {
|
||||
_context = context;
|
||||
context.AddOnBeginRequestAsync(BeginBeginRequest, EndBeginRequest, null);
|
||||
}
|
||||
|
||||
static IList<Action> _awaiting = new List<Action>();
|
||||
|
||||
public static bool InWarmup() {
|
||||
if (_awaiting == null) return false;
|
||||
lock (_awaiting) {
|
||||
return _awaiting != null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Signal() {
|
||||
lock(typeof(WarmupHttpModule)) {
|
||||
var awaiting = _awaiting;
|
||||
_awaiting = null;
|
||||
foreach (var action in awaiting) {
|
||||
action();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Await(Action action) {
|
||||
if (_awaiting == null) {
|
||||
action();
|
||||
return;
|
||||
}
|
||||
|
||||
lock(typeof(WarmupHttpModule)) {
|
||||
if (_awaiting == null) {
|
||||
action();
|
||||
return;
|
||||
}
|
||||
_awaiting.Add(action);
|
||||
}
|
||||
}
|
||||
|
||||
private IAsyncResult BeginBeginRequest(object sender, EventArgs e, AsyncCallback cb, object extradata) {
|
||||
var asyncResult = new WarmupAsyncResult(cb);
|
||||
|
||||
// host is available, process every requests, or file is processed
|
||||
if (!InWarmup() || DoBeginRequest()) {
|
||||
asyncResult.Done();
|
||||
}
|
||||
else {
|
||||
// this is the "on hold" execution path
|
||||
Await(asyncResult.Done);
|
||||
}
|
||||
|
||||
return asyncResult;
|
||||
}
|
||||
|
||||
private void EndBeginRequest(IAsyncResult ar) {
|
||||
((WarmupAsyncResult)ar).Wait();
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// return true to put request on hold (until call to Signal()) - return false to allow pipeline to execute immediately
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private bool DoBeginRequest() {
|
||||
// use the url as it was requested by the client
|
||||
// the real url might be different if it has been translated (proxy, load balancing, ...)
|
||||
var url = ToUrlString(_context.Request);
|
||||
var virtualFileCopy = WarmupFilesPath + EncodeUrl(url.Trim('/'));
|
||||
var localCopy = HostingEnvironment.MapPath(virtualFileCopy);
|
||||
|
||||
if (localCopy != null && File.Exists(localCopy)) {
|
||||
// result should not be cached, even on proxies
|
||||
_context.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
|
||||
_context.Response.Cache.SetValidUntilExpires(false);
|
||||
_context.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
|
||||
_context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
|
||||
_context.Response.Cache.SetNoStore();
|
||||
|
||||
_context.Response.WriteFile(localCopy);
|
||||
_context.Response.End();
|
||||
return true;
|
||||
}
|
||||
|
||||
// there is no local copy and the file exists
|
||||
// serve the static file
|
||||
if (File.Exists(_context.Request.PhysicalPath)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static string EncodeUrl(string url) {
|
||||
if(String.IsNullOrWhiteSpace(url)) {
|
||||
throw new ArgumentException("url can't be empty");
|
||||
}
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach(var c in url.ToLowerInvariant()) {
|
||||
// only accept alphanumeric chars
|
||||
if((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9')) {
|
||||
sb.Append(c);
|
||||
}
|
||||
// otherwise encode them in UTF8
|
||||
else {
|
||||
sb.Append("_");
|
||||
foreach(var b in Encoding.UTF8.GetBytes(new [] {c})) {
|
||||
sb.Append(b.ToString("X"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static string ToUrlString(HttpRequest request) {
|
||||
return string.Format("{0}://{1}{2}", request.Url.Scheme, request.Headers["Host"], request.RawUrl);
|
||||
}
|
||||
|
||||
private class WarmupAsyncResult : IAsyncResult {
|
||||
readonly EventWaitHandle _eventWaitHandle = new AutoResetEvent(false);
|
||||
|
||||
private readonly AsyncCallback _cb;
|
||||
|
||||
public WarmupAsyncResult(AsyncCallback cb) {
|
||||
_cb = cb;
|
||||
IsCompleted = false;
|
||||
}
|
||||
|
||||
public void Done() {
|
||||
IsCompleted = true;
|
||||
_eventWaitHandle.Set();
|
||||
_cb(this);
|
||||
}
|
||||
|
||||
public object AsyncState {
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public WaitHandle AsyncWaitHandle {
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public bool CompletedSynchronously {
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public bool IsCompleted { get; private set; }
|
||||
|
||||
public void Wait() {
|
||||
_eventWaitHandle.WaitOne();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -120,6 +120,10 @@
|
||||
<add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/>
|
||||
|
||||
</httpHandlers>
|
||||
|
||||
<httpModules>
|
||||
<add name="WarmupHttpModule" type="Orchard.Web.WarmupHttpModule, Orchard.Web"/>
|
||||
</httpModules>
|
||||
</system.web>
|
||||
<!--
|
||||
The system.webServer section is required for running ASP.NET AJAX under Internet
|
||||
@@ -128,7 +132,10 @@
|
||||
<system.webServer>
|
||||
|
||||
<validation validateIntegratedModeConfiguration="false" />
|
||||
<modules runAllManagedModulesForAllRequests="true" />
|
||||
<modules runAllManagedModulesForAllRequests="true">
|
||||
<remove name="WarmupHttpModule" />
|
||||
<add name="WarmupHttpModule" type="Orchard.Web.WarmupHttpModule, Orchard.Web"/>
|
||||
</modules>
|
||||
<handlers accessPolicy="Script">
|
||||
<!-- clear all handlers, prevents executing code file extensions, prevents returning any file contents -->
|
||||
<clear/>
|
||||
|
@@ -23,7 +23,11 @@ namespace Orchard.Data {
|
||||
void ITransactionManager.Demand() {
|
||||
if (_scope == null) {
|
||||
Logger.Debug("Creating transaction on Demand");
|
||||
_scope = new TransactionScope(TransactionScopeOption.Required);
|
||||
_scope = new TransactionScope(
|
||||
TransactionScopeOption.Required,
|
||||
new TransactionOptions {
|
||||
IsolationLevel = IsolationLevel.ReadCommitted
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,8 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Orchard.Environment.Warmup {
|
||||
public class StartupResult {
|
||||
public IOrchardHost Host { get; set; }
|
||||
public Exception Error { get; set; }
|
||||
}
|
||||
}
|
@@ -1,19 +1,29 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Orchard.Environment.Warmup {
|
||||
public static class WarmupUtility {
|
||||
private const string EncodingPattern = "[^a-z0-9]";
|
||||
|
||||
public static string EncodeUrl(string url) {
|
||||
if(String.IsNullOrWhiteSpace(url)) {
|
||||
throw new ArgumentException("url can't be empty");
|
||||
}
|
||||
|
||||
return Regex.Replace(url.ToLower(), EncodingPattern, m => "_" + Encoding.UTF8.GetBytes(m.Value).Select(b => b.ToString("X")).Aggregate((a, b) => a + b));
|
||||
}
|
||||
var sb = new StringBuilder();
|
||||
foreach (var c in url.ToLowerInvariant()) {
|
||||
// only accept alphanumeric chars
|
||||
if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9')) {
|
||||
sb.Append(c);
|
||||
}
|
||||
// otherwise encode them in UTF8
|
||||
else {
|
||||
sb.Append("_");
|
||||
foreach(var b in Encoding.UTF8.GetBytes(new [] {c})) {
|
||||
sb.Append(b.ToString("X"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -24,9 +24,7 @@ namespace Orchard.FileSystems.Dependencies {
|
||||
public Localizer T { get; set; }
|
||||
|
||||
private string PersistencePath {
|
||||
get {
|
||||
return _appDataFolder.Combine(BasePath, FileName);
|
||||
}
|
||||
get { return _appDataFolder.Combine(BasePath, FileName); }
|
||||
}
|
||||
|
||||
public DependencyDescriptor GetDescriptor(string moduleName) {
|
||||
@@ -55,10 +53,6 @@ namespace Orchard.FileSystems.Dependencies {
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetViewCompilationDependencies() {
|
||||
yield return _appDataFolder.GetVirtualPath(this.PersistencePath);
|
||||
}
|
||||
|
||||
private IEnumerable<DependencyDescriptor> ReadDependencies(string persistancePath) {
|
||||
Func<string, XName> ns = (name => XName.Get(name));
|
||||
Func<XElement, string, string> elem = (e, name) => e.Element(ns(name)).Value;
|
||||
|
@@ -23,6 +23,5 @@ namespace Orchard.FileSystems.Dependencies {
|
||||
DependencyDescriptor GetDescriptor(string moduleName);
|
||||
IEnumerable<DependencyDescriptor> LoadDescriptors();
|
||||
void StoreDescriptors(IEnumerable<DependencyDescriptor> dependencyDescriptors);
|
||||
IEnumerable<string> GetViewCompilationDependencies();
|
||||
}
|
||||
}
|
||||
|
@@ -84,14 +84,11 @@ namespace Orchard.Mvc.ViewEngines.Razor {
|
||||
provider.AssemblyBuilder.AddAssemblyReference(assembly);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var virtualDependency in entry.dependencies) {
|
||||
provider.AddVirtualPathDependency(virtualDependency);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var virtualDependency in _dependenciesFolder.GetViewCompilationDependencies()) {
|
||||
provider.AddVirtualPathDependency(virtualDependency);
|
||||
}
|
||||
}
|
||||
|
||||
private DependencyDescriptor GetModuleDependencyDescriptor(string virtualPath) {
|
||||
|
@@ -187,7 +187,6 @@
|
||||
<Compile Include="Environment\HostComponentsConfigModule.cs" />
|
||||
<Compile Include="Environment\IOrchardFrameworkAssemblies.cs" />
|
||||
<Compile Include="Environment\ViewsBackgroundCompilation.cs" />
|
||||
<Compile Include="Environment\Warmup\StartupResult.cs" />
|
||||
<Compile Include="Environment\Warmup\WarmupUtility.cs" />
|
||||
<Compile Include="Environment\WorkContextImplementation.cs" />
|
||||
<Compile Include="Environment\WorkContextModule.cs" />
|
||||
|
Reference in New Issue
Block a user