mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Merge
--HG-- branch : 1.x
This commit is contained in:
@@ -17,7 +17,7 @@ namespace Orchard.WarmupStarter {
|
||||
// so we need to simulate a "restart".
|
||||
var error = _error;
|
||||
LaunchStartupThread(registrations);
|
||||
throw error;
|
||||
throw new ApplicationException("Error during Orchard startup", error);
|
||||
}
|
||||
|
||||
// Only notify if the host has started up
|
||||
|
||||
@@ -138,6 +138,22 @@ namespace Orchard.Tests.Environment.Extensions {
|
||||
Assert.That(available, Has.Some.Property("Id").EqualTo("foo"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionDescriptorKeywordsAreCaseInsensitive() {
|
||||
|
||||
_folders.Manifests.Add("Sample", @"
|
||||
NaMe: Sample Extension
|
||||
version: 2.x
|
||||
DESCRIPTION: HELLO
|
||||
");
|
||||
|
||||
var descriptor = _manager.AvailableExtensions().Single();
|
||||
Assert.That(descriptor.Id, Is.EqualTo("Sample"));
|
||||
Assert.That(descriptor.Name, Is.EqualTo("Sample Extension"));
|
||||
Assert.That(descriptor.Version, Is.EqualTo("2.x"));
|
||||
Assert.That(descriptor.Description, Is.EqualTo("HELLO"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionDescriptorsShouldHaveNameAndVersion() {
|
||||
|
||||
|
||||
@@ -53,10 +53,10 @@ namespace Orchard.Tests.Environment.Loaders {
|
||||
|
||||
DynamicExtensionLoaderAccessor extensionLoader = _container.Resolve<DynamicExtensionLoaderAccessor>();
|
||||
StubFileSystem stubFileSystem = _container.Resolve<StubFileSystem>();
|
||||
StubFileSystem.FileEntry fileEntry = stubFileSystem.CreateFileEntry("orchard.a.csjproj");
|
||||
StubFileSystem.FileEntry fileEntry = stubFileSystem.CreateFileEntry("orchard.a.csproj");
|
||||
|
||||
// Create duplicate source files (invalid situation in reality but easy enough to test)
|
||||
_mockedStubProjectFileParser.Setup(stubProjectFileParser => stubProjectFileParser.Parse(It.IsAny<Stream>())).Returns(
|
||||
_mockedStubProjectFileParser.Setup(stubProjectFileParser => stubProjectFileParser.Parse(It.IsAny<string>())).Returns(
|
||||
new ProjectFileDescriptor { SourceFilenames = new[] { fileName1, fileName2, fileName1 } }); // duplicate file
|
||||
|
||||
IEnumerable<string> dependencies = extensionLoader.GetDependenciesAccessor(fileEntry.Name);
|
||||
@@ -76,14 +76,15 @@ namespace Orchard.Tests.Environment.Loaders {
|
||||
|
||||
DynamicExtensionLoaderAccessor extensionLoader = _container.Resolve<DynamicExtensionLoaderAccessor>();
|
||||
StubFileSystem stubFileSystem = _container.Resolve<StubFileSystem>();
|
||||
StubFileSystem.FileEntry fileEntry = stubFileSystem.CreateFileEntry("orchard.a.csjproj");
|
||||
StubFileSystem.FileEntry fileEntry2 = stubFileSystem.CreateFileEntry("orchard.b.csjproj");
|
||||
StubFileSystem.FileEntry fileEntry3 = stubFileSystem.CreateFileEntry("orchard.c.csjproj");
|
||||
StubFileSystem.FileEntry fileEntry = stubFileSystem.CreateFileEntry("orchard.a.csproj");
|
||||
StubFileSystem.FileEntry fileEntry2 = stubFileSystem.CreateFileEntry("orchard.b.csproj");
|
||||
StubFileSystem.FileEntry fileEntry3 = stubFileSystem.CreateFileEntry("orchard.c.csproj");
|
||||
|
||||
// Project a reference b and c which share a file in common
|
||||
|
||||
// Result for project a
|
||||
_mockedStubProjectFileParser.Setup(stubProjectFileParser => stubProjectFileParser.Parse(It.Is<Stream>(stream => ((StubFileSystem.FileEntryReadStream)stream).FileEntry == fileEntry)))
|
||||
_mockedStubProjectFileParser
|
||||
.Setup(stubProjectFileParser => stubProjectFileParser.Parse(It.Is<string>(virtualPath => virtualPath == "orchard.a.csproj")))
|
||||
.Returns(
|
||||
new ProjectFileDescriptor {
|
||||
SourceFilenames = new[] { fileName1, fileName2 },
|
||||
@@ -96,16 +97,16 @@ namespace Orchard.Tests.Environment.Loaders {
|
||||
},
|
||||
new ReferenceDescriptor {
|
||||
ReferenceType = ReferenceType.Project,
|
||||
SimpleName = Path.GetFileNameWithoutExtension(fileEntry2.Name),
|
||||
FullName = Path.GetFileNameWithoutExtension(fileEntry2.Name),
|
||||
SimpleName = Path.GetFileNameWithoutExtension(fileEntry3.Name),
|
||||
FullName = Path.GetFileNameWithoutExtension(fileEntry3.Name),
|
||||
Path = fileEntry3.Name
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Result for project b and c
|
||||
_mockedStubProjectFileParser.Setup(stubProjectFileParser => stubProjectFileParser.Parse(It.Is<Stream>(stream =>
|
||||
((StubFileSystem.FileEntryReadStream)stream).FileEntry == fileEntry2 || ((StubFileSystem.FileEntryReadStream)stream).FileEntry == fileEntry3)))
|
||||
_mockedStubProjectFileParser
|
||||
.Setup(stubProjectFileParser => stubProjectFileParser.Parse(It.Is<string>(virtualPath => (virtualPath == "~/orchard.b.csproj" || virtualPath == "~/orchard.c.csproj"))))
|
||||
.Returns(
|
||||
new ProjectFileDescriptor {
|
||||
SourceFilenames = new[] { commonFileName }
|
||||
@@ -116,14 +117,14 @@ namespace Orchard.Tests.Environment.Loaders {
|
||||
Assert.That(dependencies.Count(), Is.EqualTo(6), "6 results should mean no duplicates");
|
||||
|
||||
// Project files
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Equals(fileEntry.Name)), Is.Not.Null);
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Equals(fileEntry2.Name)), Is.Not.Null);
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Equals(fileEntry3.Name)), Is.Not.Null);
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Contains(fileEntry.Name)), Is.Not.Null);
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Contains(fileEntry2.Name)), Is.Not.Null);
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Contains(fileEntry3.Name)), Is.Not.Null);
|
||||
|
||||
// Individual source files
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Equals(fileName1)), Is.Not.Null);
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Equals(fileName2)), Is.Not.Null);
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Equals(commonFileName)), Is.Not.Null);
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Contains(fileName1)), Is.Not.Null);
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Contains(fileName2)), Is.Not.Null);
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Contains(commonFileName)), Is.Not.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -135,8 +136,8 @@ namespace Orchard.Tests.Environment.Loaders {
|
||||
|
||||
DynamicExtensionLoaderAccessor extensionLoader = _container.Resolve<DynamicExtensionLoaderAccessor>();
|
||||
StubFileSystem stubFileSystem = _container.Resolve<StubFileSystem>();
|
||||
StubFileSystem.FileEntry fileEntry = stubFileSystem.CreateFileEntry("orchard.a.csjproj");
|
||||
StubFileSystem.FileEntry fileEntry2 = stubFileSystem.CreateFileEntry("orchard.b.csjproj");
|
||||
StubFileSystem.FileEntry fileEntry = stubFileSystem.CreateFileEntry("orchard.a.csproj");
|
||||
StubFileSystem.FileEntry fileEntry2 = stubFileSystem.CreateFileEntry("orchard.b.csproj");
|
||||
|
||||
StubFileSystem.DirectoryEntry directoryEntry = stubFileSystem.CreateDirectoryEntry("bin");
|
||||
StubFileSystem.FileEntry fileEntry3 = directoryEntry.CreateFile("orchard.b.dll");
|
||||
@@ -144,7 +145,8 @@ namespace Orchard.Tests.Environment.Loaders {
|
||||
// Project a reference b and c which share a file in common
|
||||
|
||||
// Result for project a
|
||||
_mockedStubProjectFileParser.Setup(stubProjectFileParser => stubProjectFileParser.Parse(It.Is<Stream>(stream => ((StubFileSystem.FileEntryReadStream)stream).FileEntry == fileEntry)))
|
||||
_mockedStubProjectFileParser
|
||||
.Setup(stubProjectFileParser => stubProjectFileParser.Parse(It.Is<string>(virtualPath => virtualPath == "orchard.a.csproj")))
|
||||
.Returns(
|
||||
new ProjectFileDescriptor {
|
||||
SourceFilenames = new[] { fileName1, fileName2 },
|
||||
@@ -159,14 +161,15 @@ namespace Orchard.Tests.Environment.Loaders {
|
||||
});
|
||||
|
||||
// Result for project b and c
|
||||
_mockedStubProjectFileParser.Setup(stubProjectFileParser => stubProjectFileParser.Parse(It.Is<Stream>(stream =>
|
||||
((StubFileSystem.FileEntryReadStream)stream).FileEntry == fileEntry2)))
|
||||
_mockedStubProjectFileParser
|
||||
.Setup(stubProjectFileParser => stubProjectFileParser.Parse(It.Is<string>(virtualPath => virtualPath == "~/orchard.b.csproj")))
|
||||
.Returns(
|
||||
new ProjectFileDescriptor {
|
||||
SourceFilenames = new[] { commonFileName }
|
||||
});
|
||||
|
||||
_mockedDependenciesFolder.Setup(dependenciesFolder => dependenciesFolder.GetDescriptor(It.Is<string>(moduleName => moduleName == Path.GetDirectoryName(fileEntry2.Name))))
|
||||
_mockedDependenciesFolder
|
||||
.Setup(dependenciesFolder => dependenciesFolder.GetDescriptor(It.Is<string>(moduleName => moduleName == Path.GetDirectoryName(fileEntry2.Name))))
|
||||
.Returns(
|
||||
new DependencyDescriptor {
|
||||
VirtualPath = Path.Combine(directoryEntry.Name, fileEntry3.Name)
|
||||
@@ -177,14 +180,14 @@ namespace Orchard.Tests.Environment.Loaders {
|
||||
Assert.That(dependencies.Count(), Is.EqualTo(6), "6 results should mean no duplicates");
|
||||
|
||||
// Project files
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Equals(fileEntry.Name)), Is.Not.Null);
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Equals(fileEntry2.Name)), Is.Not.Null);
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Equals(Path.Combine(directoryEntry.Name, fileEntry3.Name))), Is.Not.Null);
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Contains(fileEntry.Name)), Is.Not.Null);
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Contains(fileEntry2.Name)), Is.Not.Null);
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Contains(Path.Combine(directoryEntry.Name, fileEntry3.Name))), Is.Not.Null);
|
||||
|
||||
// Individual source files
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Equals(fileName1)), Is.Not.Null);
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Equals(fileName2)), Is.Not.Null);
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Equals(commonFileName)), Is.Not.Null);
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Contains(fileName1)), Is.Not.Null);
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Contains(fileName2)), Is.Not.Null);
|
||||
Assert.That(dependencies.FirstOrDefault(dep => dep.Contains(commonFileName)), Is.Not.Null);
|
||||
}
|
||||
|
||||
internal class DynamicExtensionLoaderAccessor : DynamicExtensionLoader {
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
using System.Xml;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Xml;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Core.Common.Settings;
|
||||
using Orchard.Core.Common.ViewModels;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Security;
|
||||
@@ -16,6 +20,9 @@ namespace Orchard.Core.Common.Drivers {
|
||||
private readonly IMembershipService _membershipService;
|
||||
private readonly IClock _clock;
|
||||
|
||||
private const string DatePattern = "M/d/yyyy";
|
||||
private const string TimePattern = "h:mm tt";
|
||||
|
||||
public CommonPartDriver(
|
||||
IOrchardServices services,
|
||||
IContentManager contentManager,
|
||||
@@ -51,9 +58,7 @@ namespace Orchard.Core.Common.Drivers {
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(CommonPart part, dynamic shapeHelper) {
|
||||
return Combined(
|
||||
OwnerEditor(part, null, shapeHelper),
|
||||
ContainerEditor(part, null, shapeHelper));
|
||||
return BuildEditor(part, null, shapeHelper);
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(CommonPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
@@ -61,9 +66,24 @@ namespace Orchard.Core.Common.Drivers {
|
||||
part.ModifiedUtc = _clock.UtcNow;
|
||||
part.VersionModifiedUtc = _clock.UtcNow;
|
||||
|
||||
return Combined(
|
||||
OwnerEditor(part, updater, shapeHelper),
|
||||
ContainerEditor(part, updater, shapeHelper));
|
||||
return BuildEditor(part, updater, shapeHelper);
|
||||
}
|
||||
|
||||
private DriverResult BuildEditor(CommonPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
List<DriverResult> parts = new List<DriverResult>();
|
||||
CommonTypePartSettings commonTypePartSettings = GetTypeSettings(part);
|
||||
|
||||
if (commonTypePartSettings.ShowOwnerEditor) {
|
||||
parts.Add(OwnerEditor(part, updater, shapeHelper));
|
||||
}
|
||||
|
||||
if (commonTypePartSettings.ShowCreatedUtcEditor) {
|
||||
parts.Add(CreatedUtcEditor(part, updater, shapeHelper));
|
||||
}
|
||||
|
||||
parts.Add(ContainerEditor(part, updater, shapeHelper));
|
||||
|
||||
return Combined(parts.ToArray());
|
||||
}
|
||||
|
||||
DriverResult OwnerEditor(CommonPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
@@ -95,6 +115,37 @@ namespace Orchard.Core.Common.Drivers {
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Common.Owner", Model: model, Prefix: Prefix));
|
||||
}
|
||||
|
||||
DriverResult CreatedUtcEditor(CommonPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
CreatedUtcEditorViewModel model = new CreatedUtcEditorViewModel();
|
||||
if (part.CreatedUtc != null) {
|
||||
model.CreatedDate = part.CreatedUtc.Value.ToLocalTime().ToString(DatePattern, CultureInfo.InvariantCulture);
|
||||
model.CreatedTime = part.CreatedUtc.Value.ToLocalTime().ToString(TimePattern, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
if (updater != null) {
|
||||
updater.TryUpdateModel(model, Prefix, null, null);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(model.CreatedDate) && !string.IsNullOrWhiteSpace(model.CreatedTime)) {
|
||||
DateTime createdUtc;
|
||||
string parseDateTime = String.Concat(model.CreatedDate, " ", model.CreatedTime);
|
||||
|
||||
// use an english culture as it is the one used by jQuery.datepicker by default
|
||||
if (DateTime.TryParse(parseDateTime, CultureInfo.GetCultureInfo("en-US"), DateTimeStyles.AssumeLocal, out createdUtc)) {
|
||||
part.CreatedUtc = createdUtc.ToUniversalTime();
|
||||
}
|
||||
else {
|
||||
updater.AddModelError(Prefix, T("{0} is an invalid date and time", parseDateTime));
|
||||
}
|
||||
}
|
||||
else {
|
||||
updater.AddModelError(Prefix, T("Both the date and time need to be specified."));
|
||||
}
|
||||
}
|
||||
|
||||
return ContentShape("Parts_Common_CreatedUtc_Edit",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Common.CreatedUtc", Model: model, Prefix: Prefix));
|
||||
}
|
||||
|
||||
DriverResult ContainerEditor(CommonPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
var currentUser = _authenticationService.GetAuthenticatedUser();
|
||||
if (!_authorizationService.TryCheckAccess(StandardPermissions.SiteOwner, currentUser, part)) {
|
||||
@@ -124,6 +175,10 @@ namespace Orchard.Core.Common.Drivers {
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Common.Container", Model: model, Prefix: Prefix));
|
||||
}
|
||||
|
||||
private static CommonTypePartSettings GetTypeSettings(CommonPart part) {
|
||||
return part.Settings.GetModel<CommonTypePartSettings>();
|
||||
}
|
||||
|
||||
protected override void Importing(CommonPart part, ImportContentContext context) {
|
||||
var owner = context.Attribute(part.PartDefinition.Name, "Owner");
|
||||
if (owner != null) {
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
<!-- edit "shape" -->
|
||||
<Place Parts_Common_Body_Edit="Content:2"/>
|
||||
<Place Parts_Common_Owner_Edit="Content:20"/>
|
||||
<Place Parts_Common_CreatedUtc_Edit="Content:18"/>
|
||||
<Place Parts_Common_Container_Edit="Content:20"/>
|
||||
<Place Fields_Common_Text_Edit="Content:2.5"/>
|
||||
<!-- default positioning -->
|
||||
|
||||
9
src/Orchard.Web/Core/Common/ResourceManifest.cs
Normal file
9
src/Orchard.Web/Core/Common/ResourceManifest.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using Orchard.UI.Resources;
|
||||
|
||||
namespace Orchard.Core.Common {
|
||||
public class ResourceManifest : IResourceManifestProvider {
|
||||
public void BuildManifests(ResourceManifestBuilder builder) {
|
||||
builder.Add().DefineStyle("Common_DatePicker").SetUrl("orchard-common-datetime.css");
|
||||
}
|
||||
}
|
||||
}
|
||||
38
src/Orchard.Web/Core/Common/Settings/CommonSettings.cs
Normal file
38
src/Orchard.Web/Core/Common/Settings/CommonSettings.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
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.Core.Common.Settings {
|
||||
public class CommonTypePartSettings {
|
||||
public CommonTypePartSettings() {
|
||||
ShowOwnerEditor = true;
|
||||
}
|
||||
|
||||
public bool ShowCreatedUtcEditor { get; set; }
|
||||
public bool ShowOwnerEditor { get; set; }
|
||||
}
|
||||
|
||||
public class CommonSettingsHooks : ContentDefinitionEditorEventsBase {
|
||||
public override IEnumerable<TemplateViewModel> TypePartEditor(ContentTypePartDefinition definition) {
|
||||
if (definition.PartDefinition.Name != "CommonPart")
|
||||
yield break;
|
||||
|
||||
var model = definition.Settings.GetModel<CommonTypePartSettings>();
|
||||
yield return DefinitionTemplate(model);
|
||||
}
|
||||
|
||||
public override IEnumerable<TemplateViewModel> TypePartEditorUpdate(ContentTypePartDefinitionBuilder builder, IUpdateModel updateModel) {
|
||||
if (builder.Name != "CommonPart")
|
||||
yield break;
|
||||
|
||||
var model = new CommonTypePartSettings();
|
||||
updateModel.TryUpdateModel(model, "CommonTypePartSettings", null, null);
|
||||
builder.WithSetting("CommonTypePartSettings.ShowCreatedUtcEditor", model.ShowCreatedUtcEditor.ToString());
|
||||
builder.WithSetting("CommonTypePartSettings.ShowOwnerEditor", model.ShowOwnerEditor.ToString());
|
||||
yield return DefinitionTemplate(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
21
src/Orchard.Web/Core/Common/Styles/Web.config
Normal file
21
src/Orchard.Web/Core/Common/Styles/Web.config
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="webpages:Enabled" value="false" />
|
||||
</appSettings>
|
||||
<system.web>
|
||||
<httpHandlers>
|
||||
<!-- iis6 - for any request in this location, return via managed static file handler -->
|
||||
<add path="*" verb="*" type="System.Web.StaticFileHandler" />
|
||||
</httpHandlers>
|
||||
</system.web>
|
||||
<system.webServer>
|
||||
<handlers accessPolicy="Script,Read">
|
||||
<!--
|
||||
iis7 - for any request to a file exists on disk, return it via native http module.
|
||||
accessPolicy 'Script' is to allow for a managed 404 page.
|
||||
-->
|
||||
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule" preCondition="integratedMode" resourceType="File" requireAccess="Read" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
@@ -0,0 +1,14 @@
|
||||
fieldset.createdutc-datetime {
|
||||
float:left;
|
||||
clear:none;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
fieldset.createdutc-datetime legend {
|
||||
display:none;
|
||||
}
|
||||
fieldset.createdutc-datetime input {
|
||||
padding:1px;
|
||||
text-align:center;
|
||||
color:#666;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Orchard.Core.Common.ViewModels {
|
||||
public class CreatedUtcEditorViewModel {
|
||||
public string CreatedDate { get; set; }
|
||||
public string CreatedTime { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
@model Orchard.Core.Common.Settings.CommonTypePartSettings
|
||||
<fieldset>
|
||||
@Html.CheckBoxFor(m => m.ShowCreatedUtcEditor)
|
||||
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.ShowCreatedUtcEditor)">@T("Show editor for creation date time")</label>
|
||||
@Html.ValidationMessageFor(m => m.ShowCreatedUtcEditor)
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
@Html.CheckBoxFor(m => m.ShowOwnerEditor)
|
||||
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.ShowOwnerEditor)">@T("Show editor for owner")</label>
|
||||
@Html.ValidationMessageFor(m => m.ShowOwnerEditor)
|
||||
</fieldset>
|
||||
@@ -0,0 +1,41 @@
|
||||
@model CreatedUtcEditorViewModel
|
||||
@using Orchard.Core.Common.ViewModels;
|
||||
@{
|
||||
Script.Require("jQueryUtils_TimePicker");
|
||||
Script.Require("jQueryUI_DatePicker");
|
||||
Style.Require("Common_DatePicker");
|
||||
Style.Require("jQueryUtils_TimePicker");
|
||||
Style.Require("jQueryUI_DatePicker");
|
||||
}
|
||||
<fieldset class="createdutc-datetime">
|
||||
@Html.LabelFor(m => m.CreatedDate, T("Created On"))
|
||||
<label class="forpicker" for="@ViewData.TemplateInfo.GetFullHtmlFieldId("CreatedDate")">@T("Date")</label>
|
||||
@Html.EditorFor(m => m.CreatedDate)
|
||||
<label class="forpicker" for="@ViewData.TemplateInfo.GetFullHtmlFieldId("CreatedTime")">@T("Time")</label>
|
||||
@Html.EditorFor(m => m.CreatedTime)
|
||||
</fieldset>
|
||||
@using(Script.Foot()) {
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
$(function () {
|
||||
var clearHint = function ($this) { if ($this.val() == $this.data("hint")) { $this.removeClass("hinted").val("") } };
|
||||
var resetHint = function ($this) { setTimeout(function () { if (!$this.val()) { $this.addClass("hinted").val($this.data("hint")) } }, 300) };
|
||||
@* todo: (heskew) make a plugin *@
|
||||
$("label.forpicker").each(function () {
|
||||
var $this = $(this);
|
||||
var pickerInput = $("#" + $this.attr("for"));
|
||||
if (!pickerInput.val()) {
|
||||
pickerInput.data("hint", $this.text());
|
||||
pickerInput.addClass("hinted")
|
||||
.val(pickerInput.data("hint"))
|
||||
.focus(function() {clearHint($(this));})
|
||||
.blur(function() {resetHint($(this));});
|
||||
$this.closest("form").submit(function() {clearHint(pickerInput); pickerInput = 0;});
|
||||
}
|
||||
});
|
||||
$('#@ViewData.TemplateInfo.GetFullHtmlFieldId("CreatedDate")').datepicker({ showAnim: "" }).focus(function () { $('#@ViewData.TemplateInfo.GetFullHtmlFieldId("Command_Created")').attr("checked", "checked") });
|
||||
$('#@ViewData.TemplateInfo.GetFullHtmlFieldId("CreatedTime")').timepickr({ showAnim: "" }).focus(function () { $('#@ViewData.TemplateInfo.GetFullHtmlFieldId("Command_Created")').attr("checked", "checked") });
|
||||
})
|
||||
//]]>
|
||||
</script>
|
||||
}
|
||||
@@ -66,7 +66,10 @@
|
||||
<Compile Include="Common\Models\CommonPartVersionRecord.cs" />
|
||||
<Compile Include="Common\Models\IdentityPartRecord.cs" />
|
||||
<Compile Include="Common\Models\IdentityPart.cs" />
|
||||
<Compile Include="Common\ResourceManifest.cs" />
|
||||
<Compile Include="Common\Services\XmlRpcHandler.cs" />
|
||||
<Compile Include="Common\Settings\CommonSettings.cs" />
|
||||
<Compile Include="Common\ViewModels\CreatedUtcEditorViewModel.cs" />
|
||||
<Compile Include="Containers\Controllers\ItemController.cs" />
|
||||
<Compile Include="Containers\Drivers\ContainablePartDriver.cs" />
|
||||
<Compile Include="Containers\Drivers\ContainerPartDriver.cs" />
|
||||
@@ -243,6 +246,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Common\Module.txt" />
|
||||
<Content Include="Common\Styles\orchard-common-datetime.css" />
|
||||
<Content Include="Common\Views\DefinitionTemplates\BodyTypePartSettings.cshtml" />
|
||||
<Content Include="Common\Views\DefinitionTemplates\BodyPartSettings.cshtml" />
|
||||
<Content Include="Common\Views\Fields.Common.Text.cshtml" />
|
||||
@@ -427,6 +431,17 @@
|
||||
<ItemGroup>
|
||||
<Content Include="web.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Common\Views\DefinitionTemplates\CommonTypePartSettings.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Common\Views\EditorTemplates\Parts.Common.CreatedUtc.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Common\Styles\Web.config">
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
</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.
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace Orchard.Core.Routable.Services {
|
||||
|
||||
public IEnumerable<IRoutableAspect> GetSimilarPaths(string path) {
|
||||
return
|
||||
_contentManager.Query().Join<RoutePartRecord>()
|
||||
_contentManager.Query<RoutePart, RoutePartRecord>()
|
||||
.List()
|
||||
.Select(i => i.As<RoutePart>())
|
||||
.Where(routable => routable.Path != null && routable.Path.StartsWith(path, StringComparison.OrdinalIgnoreCase))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@using System.Web.Mvc;
|
||||
|
||||
<div class="user-display">
|
||||
@if (Request.IsAuthenticated) {
|
||||
@if (WorkContext.CurrentUser != null) {
|
||||
<span class="user-actions welcome">
|
||||
@T("Welcome, <strong>{0}</strong>!", new HtmlString(Html.ActionLink( WorkContext.CurrentUser.UserName, "ChangePassword", new { Controller = "Account", Area = "Orchard.Users" }).ToString()))
|
||||
</span>
|
||||
|
||||
@@ -46,7 +46,8 @@ namespace Orchard.Blogs {
|
||||
ContentDefinitionManager.AlterTypeDefinition("BlogPost",
|
||||
cfg => cfg
|
||||
.WithPart("BlogPostPart")
|
||||
.WithPart("CommonPart")
|
||||
.WithPart("CommonPart", p => p
|
||||
.WithSetting("CommonTypePartSettings.ShowCreatedUtcEditor", "true"))
|
||||
.WithPart("PublishLaterPart")
|
||||
.WithPart("RoutePart")
|
||||
.WithPart("BodyPart")
|
||||
|
||||
@@ -25,13 +25,13 @@
|
||||
</div>
|
||||
}
|
||||
}
|
||||
else if(!Request.IsAuthenticated && !AuthorizedFor(Permissions.AddComment)) {
|
||||
else if (WorkContext.CurrentUser == null && !AuthorizedFor(Permissions.AddComment)) {
|
||||
<h2 id="add-comment">@T("Add a Comment")</h2>
|
||||
<p class="info message">@T("You must {0} to comment.", Html.ActionLink(T("log on").ToString(), "LogOn", new { Controller = "Account", Area = "Orchard.Users", ReturnUrl = string.Format("{0}#addacomment", Context.Request.RawUrl) }))</p>
|
||||
} else {
|
||||
using (Html.BeginForm("Create", "Comment", new { area = "Orchard.Comments" }, FormMethod.Post, new { @class = "comment-form" })) {
|
||||
@Html.ValidationSummary()
|
||||
if (!Request.IsAuthenticated) {
|
||||
if (WorkContext.CurrentUser == null) {
|
||||
|
||||
<fieldset class="who">
|
||||
<legend id="add-comment">@T("Add a Comment")</legend>
|
||||
@@ -55,7 +55,7 @@ using (Html.BeginForm("Create", "Comment", new { area = "Orchard.Comments" }, Fo
|
||||
@Html.Hidden("Email", WorkContext.CurrentUser.Email ?? "")
|
||||
}
|
||||
|
||||
<h2 id="commenter">@if (Request.IsAuthenticated) { @T("Hi, {0}!", Html.Encode(WorkContext.CurrentUser.UserName))}</h2>
|
||||
<h2 id="commenter">@if (WorkContext.CurrentUser != null) { @T("Hi, {0}!", Html.Encode(WorkContext.CurrentUser.UserName))}</h2>
|
||||
<fieldset class="what">
|
||||
<ol>
|
||||
<li>
|
||||
|
||||
@@ -190,7 +190,7 @@ namespace Orchard.DesignerTools.Services {
|
||||
}
|
||||
}
|
||||
|
||||
private static string FormatJsonValue(string value) {
|
||||
public static string FormatJsonValue(string value) {
|
||||
// replace " by \" in json strings
|
||||
return value.Replace(@"\", @"\\").Replace("\"", @"\""").Replace("\r\n", @"\n").Replace("\r", @"\n").Replace("\n", @"\n");
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
@using Orchard.Utility.Extensions;
|
||||
@using Orchard.DesignerTools.Services;
|
||||
|
||||
@functions {
|
||||
string FormatShapeName(string shape) {
|
||||
@@ -59,14 +60,14 @@ shapeTracingMetadataHost[@Model.ShapeId].shape = {
|
||||
</text>
|
||||
}
|
||||
],
|
||||
html: '@RemoveEmptyLines(RemoveBeacons(Display(Model.ChildContent).ToString())).Replace(Environment.NewLine, "\\n")',
|
||||
templateContent: '@(String.IsNullOrWhiteSpace((string)Model.TemplateContent) ? @T("Content not available as coming from source code.") : @Model.TemplateContent.Replace(Environment.NewLine, "\\n"))',
|
||||
html: '@ShapeTracingFactory.FormatJsonValue(RemoveEmptyLines(RemoveBeacons(Display(Model.ChildContent).ToString())))',
|
||||
templateContent: '@(ShapeTracingFactory.FormatJsonValue(String.IsNullOrWhiteSpace((string)Model.TemplateContent) ? @T("Content not available as coming from source code.").ToString() : (string)Model.TemplateContent))',
|
||||
model: { @(new MvcHtmlString((string)@Model.Dump)) }
|
||||
};
|
||||
|
||||
@if (!String.IsNullOrEmpty((string)Model.PlacementSource) && (WorkContext.HttpContext.Items[(string)Model.PlacementSource] == null)) {
|
||||
WorkContext.HttpContext.Items[(string)Model.PlacementSource] = new object();
|
||||
<text>shapeTracingMetadataHost.placement['@Model.PlacementSource.ToString()'] = '@Model.PlacementContent.Replace(Environment.NewLine, "\\n")'; </text>
|
||||
<text>shapeTracingMetadataHost.placement['@Model.PlacementSource.ToString()'] = '@ShapeTracingFactory.FormatJsonValue((string)Model.PlacementContent)'; </text>
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@@ -8,23 +8,18 @@ namespace Orchard.Experimental {
|
||||
public class TestingListsMigrations : DataMigrationImpl {
|
||||
public int Create() {
|
||||
ContentDefinitionManager.AlterTypeDefinition("ListItem",
|
||||
cfg => cfg
|
||||
.WithPart("CommonPart")
|
||||
.WithPart("RoutePart")
|
||||
.WithPart("BodyPart")
|
||||
.WithPart("ContainablePart")
|
||||
.Creatable());
|
||||
cfg => cfg
|
||||
.WithPart("CommonPart")
|
||||
.WithPart("RoutePart")
|
||||
.WithPart("BodyPart")
|
||||
.WithPart("ContainablePart")
|
||||
.Creatable()
|
||||
);
|
||||
|
||||
ContentDefinitionManager.AlterTypeDefinition("Page",
|
||||
cfg => cfg
|
||||
.WithPart("ContainablePart"));
|
||||
|
||||
//ContentDefinitionManager.AlterTypeDefinition("ListWidget",
|
||||
// cfg => cfg
|
||||
// .WithPart("CommonPart")
|
||||
// .WithPart("WidgetPart")
|
||||
// .WithPart("ListWidgetPart")
|
||||
// .WithSetting("Stereotype", "Widget"));
|
||||
cfg => cfg
|
||||
.WithPart("ContainablePart")
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ImportExport.Services;
|
||||
@@ -76,8 +75,6 @@ namespace Orchard.ImportExport.Controllers {
|
||||
exportOptions.VersionHistoryOptions = (VersionHistoryOptions)Enum.Parse(typeof(VersionHistoryOptions), viewModel.DataImportChoice, true);
|
||||
}
|
||||
var exportFilePath = _importExportService.Export(contentTypesToExport, exportOptions);
|
||||
Services.Notifier.Information(T("Your export file has been created at {0}", exportFilePath));
|
||||
|
||||
return File(exportFilePath, "text/xml", "export.xml");
|
||||
}
|
||||
catch (Exception exception) {
|
||||
|
||||
@@ -59,8 +59,8 @@
|
||||
@foreach (var mediaFile in Model.MediaFiles) {
|
||||
<tr>
|
||||
<td>
|
||||
<input type="checkbox" value="true" name="@T("Checkbox.File.{0}", mediaFile.Name)"/>
|
||||
<input type="hidden" value="@T(Model.MediaPath)" name="@T(mediaFile.Name)" />
|
||||
<input type="checkbox" value="true" name="Checkbox.File.@mediaFile.Name"/>
|
||||
<input type="hidden" value="@Model.MediaPath" name="@mediaFile.Name" />
|
||||
</td>
|
||||
<td>
|
||||
@Html.ActionLink(mediaFile.Name, "EditMedia", new { name = mediaFile.Name,
|
||||
@@ -79,7 +79,7 @@
|
||||
@foreach (var mediaFolder in Model.MediaFolders) {
|
||||
<tr>
|
||||
<td>
|
||||
<input type="checkbox" value="true" name="@T("Checkbox.Folder.{0}", mediaFolder.Name)"/>
|
||||
<input type="checkbox" value="true" name="Checkbox.Folder.@mediaFolder.Name"/>
|
||||
<input type="hidden" value="@mediaFolder.MediaPath" name="@mediaFolder.Name" />
|
||||
</td>
|
||||
<td>
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
</thead>
|
||||
@foreach (var mediaFolder in Model.MediaFolders) {
|
||||
<tr>
|
||||
<td><input type="checkbox" value="true" name="@T("Checkbox.{0}", mediaFolder.Name)"/></td>
|
||||
<td><input type="checkbox" value="true" name="Checkbox.@mediaFolder.Name"/></td>
|
||||
@* todo: (heskew) this URL needs to be determined from current module location *@
|
||||
<td>
|
||||
<img src="@Href("~/Modules/Orchard.Media/Content/Admin/images/folder.gif")" height="16" width="16" class="mediaTypeIcon" alt="@T("Folder")" />
|
||||
|
||||
@@ -123,8 +123,14 @@
|
||||
$(prefix + "loader").attr("src", src);
|
||||
$(prefix + "src").val(src);
|
||||
|
||||
var disabled = src ? "" : "disabled";
|
||||
$(prefix + "insert").attr("disabled", disabled).toggleClass("disabled", !!disabled);
|
||||
var insertButton = $(prefix + "insert");
|
||||
if (src) {
|
||||
insertButton.removeAttr("disabled");
|
||||
}
|
||||
else {
|
||||
insertButton.attr("disabled", "disabled");
|
||||
}
|
||||
insertButton.toggleClass("disabled", !src);
|
||||
}
|
||||
|
||||
function getIdPrefix(e) {
|
||||
|
||||
@@ -41,8 +41,8 @@ namespace Orchard.Packaging.Services {
|
||||
IEnumerable<IPackage> repositoryPackages = SourceRepository.GetPackages().ToList();
|
||||
IEnumerable<IPackage> packages = from extension in _extensionManager.AvailableExtensions()
|
||||
let id = PackageBuilder.BuildPackageId(extension.Id, extension.ExtensionType)
|
||||
let version = Version.Parse(extension.Version)
|
||||
let package = repositoryPackages.FirstOrDefault(p => p.Id == id && p.Version == version)
|
||||
let version = extension.Version != null ? Version.Parse(extension.Version) : null
|
||||
let package = repositoryPackages.FirstOrDefault(p => p.Id == id && (version == null || p.Version == version))
|
||||
where package != null
|
||||
select package;
|
||||
|
||||
|
||||
@@ -6,8 +6,9 @@ namespace Orchard.Pages {
|
||||
public class Migrations : DataMigrationImpl {
|
||||
public int Create() {
|
||||
ContentDefinitionManager.AlterTypeDefinition("Page",
|
||||
cfg=>cfg
|
||||
.WithPart("CommonPart")
|
||||
cfg => cfg
|
||||
.WithPart("CommonPart", p => p
|
||||
.WithSetting("CommonTypePartSettings.ShowCreatedUtcEditor", "true"))
|
||||
.WithPart("PublishLaterPart")
|
||||
.WithPart("RoutePart")
|
||||
.WithPart("BodyPart")
|
||||
|
||||
@@ -65,7 +65,12 @@ namespace Orchard.Widgets.Filters {
|
||||
// Build and add shape to zone.
|
||||
var zones = workContext.Layout.Zones;
|
||||
foreach (var widgetPart in widgetParts) {
|
||||
if (activeLayerIds.Contains(widgetPart.As<ICommonPart>().Container.ContentItem.Id)) {
|
||||
var commonPart = widgetPart.As<ICommonPart>();
|
||||
if (commonPart == null || commonPart.Container == null) {
|
||||
Logger.Warning("The widget '{0}' is has no assigned layer or the layer does not exist.", widgetPart.Title);
|
||||
continue;
|
||||
}
|
||||
if (activeLayerIds.Contains(commonPart.Container.ContentItem.Id)) {
|
||||
var widgetShape = _contentManager.BuildDisplay(widgetPart);
|
||||
zones[widgetPart.Record.Zone].Add(widgetShape, widgetPart.Record.Position);
|
||||
}
|
||||
|
||||
@@ -47,8 +47,8 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Scripts\jquery-1.5.2.js" />
|
||||
<Content Include="Scripts\jquery-1.5.2.min.js" />
|
||||
<Content Include="Scripts\jquery-1.6.1.js" />
|
||||
<Content Include="Scripts\jquery-1.6.1.min.js" />
|
||||
<Content Include="Scripts\jquery.effects.blind.js" />
|
||||
<Content Include="Scripts\jquery.effects.blind.min.js" />
|
||||
<Content Include="Scripts\jquery.effects.bounce.js" />
|
||||
|
||||
@@ -2,7 +2,7 @@ namespace Orchard.UI.Resources {
|
||||
public class ResourceManifest : IResourceManifestProvider {
|
||||
public void BuildManifests(ResourceManifestBuilder builder) {
|
||||
var manifest = builder.Add();
|
||||
manifest.DefineScript("jQuery").SetUrl("jquery-1.5.2.min.js", "jquery-1.5.2.js").SetVersion("1.5.2");
|
||||
manifest.DefineScript("jQuery").SetUrl("jquery-1.6.1.min.js", "jquery-1.6.1.js").SetVersion("1.6.1");
|
||||
|
||||
// UI Core
|
||||
manifest.DefineScript("jQueryUI_Core").SetUrl("jquery.ui.core.min.js", "jquery.ui.core.js").SetVersion("1.8.10").SetDependencies("jQuery");
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
18
src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery-1.6.1.min.js
vendored
Normal file
18
src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery-1.6.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
|
||||
(function(){tinymce.create("tinymce.plugins.Orchard.MediaPicker",{init:function(b,d){b.addCommand("mceMediaPicker",function(){b.focus();var c,a=b.selection.getContent();if(a){a=a.replace(/\<IMG/gi,"<editimg");a=$(a).filter("editimg");if(a.length)c={src:a.attr("src"),"class":a.attr("class"),style:a.css("cssText"),alt:a.attr("alt"),width:a.attr("width"),height:a.attr("height"),align:a.attr("align")}}jQuery("#"+b.id).trigger("orchard-admin-pickimage-open",{img:c,uploadMediaPath:b.getParam("mediapicker_uploadpath"),
|
||||
callback:function(e){b.focus();b.selection.setContent(e.img.html)}})});b.addButton("mediapicker",{title:b.getParam("mediapicker_title"),cmd:"mceMediaPicker",image:d+"/img/picture_add.png"})},createControl:function(){return null},getInfo:function(){return{longname:"Orchard MediaPicker Plugin",author:"Dave Reed",authorurl:"http://orchardproject.net",infourl:"http://orchardproject.net",version:"1.1"}}});tinymce.PluginManager.add("mediapicker",tinymce.plugins.Orchard.MediaPicker)})();
|
||||
(function(){tinymce.create("tinymce.plugins.Orchard.MediaPicker",{init:function(b,d){b.addCommand("mceMediaPicker",function(){b.focus();var c,a=b.selection.getContent();a&&(a=a.replace(/\<IMG/gi,"<editimg"),a=$(a).filter("editimg"),a.length&&(c={src:a.attr("src"),"class":a.attr("class"),style:a.css("cssText"),alt:a.attr("alt"),width:a.attr("width"),height:a.attr("height"),align:a.attr("align")}));jQuery("#"+b.id).trigger("orchard-admin-pickimage-open",{img:c,uploadMediaPath:jQuery("#"+b.id).data("mediapicker-uploadpath"),
|
||||
callback:function(a){b.focus();b.selection.setContent(a.img.html)}})});b.addButton("mediapicker",{title:jQuery("#"+b.id).data("mediapicker-title"),cmd:"mceMediaPicker",image:d+"/img/picture_add.png"})},createControl:function(){return null},getInfo:function(){return{longname:"Orchard MediaPicker Plugin",author:"Dave Reed",authorurl:"http://orchardproject.net",infourl:"http://orchardproject.net",version:"1.1"}}});tinymce.PluginManager.add("mediapicker",tinymce.plugins.Orchard.MediaPicker)})();
|
||||
@@ -72,10 +72,13 @@ namespace Orchard.Data {
|
||||
NHibernate.Cfg.Environment.UseReflectionOptimizer = false;
|
||||
|
||||
Configuration config = GetConfiguration();
|
||||
return config.BuildSessionFactory();
|
||||
var result = config.BuildSessionFactory();
|
||||
Logger.Debug("Done building session factory");
|
||||
return result;
|
||||
}
|
||||
|
||||
private Configuration BuildConfiguration() {
|
||||
Logger.Debug("Building configuration");
|
||||
var parameters = GetSessionFactoryParameters();
|
||||
|
||||
var config = _sessionConfigurationCache.GetConfiguration(() =>
|
||||
@@ -100,6 +103,7 @@ namespace Orchard.Data {
|
||||
}
|
||||
#endregion
|
||||
|
||||
Logger.Debug("Done Building configuration");
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ namespace Orchard.Environment {
|
||||
void IOrchardHost.Initialize() {
|
||||
Logger.Information("Initializing");
|
||||
BuildCurrent();
|
||||
Logger.Information("Initialized");
|
||||
}
|
||||
|
||||
void IOrchardHost.ReloadExtensions() {
|
||||
@@ -98,19 +99,26 @@ namespace Orchard.Environment {
|
||||
}
|
||||
|
||||
IEnumerable<ShellContext> CreateAndActivate() {
|
||||
Logger.Information("Start creation of shells");
|
||||
|
||||
IEnumerable<ShellContext> result;
|
||||
var allSettings = _shellSettingsManager.LoadSettings();
|
||||
if (allSettings.Any()) {
|
||||
return allSettings.Select(
|
||||
result = allSettings.Select(
|
||||
settings => {
|
||||
var context = CreateShellContext(settings);
|
||||
ActivateShell(context);
|
||||
return context;
|
||||
});
|
||||
}
|
||||
else {
|
||||
var setupContext = CreateSetupContext();
|
||||
ActivateShell(setupContext);
|
||||
result = new[] {setupContext};
|
||||
}
|
||||
|
||||
var setupContext = CreateSetupContext();
|
||||
ActivateShell(setupContext);
|
||||
return new[] { setupContext };
|
||||
Logger.Information("Done creating shells");
|
||||
return result;
|
||||
}
|
||||
|
||||
private void ActivateShell(ShellContext context) {
|
||||
|
||||
@@ -48,8 +48,7 @@ namespace Orchard.Environment.Extensions.Compilers {
|
||||
return;
|
||||
|
||||
try {
|
||||
using (var stream = _virtualPathProvider.OpenFile(context.VirtualPath)) {
|
||||
var projectFileDescriptor = _projectFileParser.Parse(stream);
|
||||
var projectFileDescriptor = _projectFileParser.Parse(context.VirtualPath);
|
||||
|
||||
// Add source files
|
||||
var directory = _virtualPathProvider.GetDirectoryName(context.VirtualPath);
|
||||
@@ -100,7 +99,6 @@ namespace Orchard.Environment.Extensions.Compilers {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
//Note: we need to embed the "e.Message" in the exception text because
|
||||
// ASP.NET build manager "swallows" inner exceptions from this method.
|
||||
|
||||
@@ -3,12 +3,38 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Orchard.Caching;
|
||||
using Orchard.FileSystems.WebSite;
|
||||
|
||||
namespace Orchard.Environment.Extensions.Compilers {
|
||||
public class DefaultProjectFileParser : IProjectFileParser {
|
||||
private readonly IWebSiteFolder _webSiteFolder;
|
||||
private readonly ICacheManager _cacheManager;
|
||||
|
||||
public DefaultProjectFileParser(IWebSiteFolder webSiteFolder, ICacheManager cacheManager) {
|
||||
_webSiteFolder = webSiteFolder;
|
||||
_cacheManager = cacheManager;
|
||||
}
|
||||
|
||||
public ProjectFileDescriptor Parse(string virtualPath) {
|
||||
return _cacheManager.Get(virtualPath,
|
||||
ctx => {
|
||||
ctx.Monitor(_webSiteFolder.WhenPathChanges(virtualPath));
|
||||
string content = _webSiteFolder.ReadFile(virtualPath);
|
||||
using (var reader = new StringReader(content)) {
|
||||
return Parse(reader);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ProjectFileDescriptor Parse(Stream stream) {
|
||||
var document = XDocument.Load(XmlReader.Create(stream));
|
||||
using (var reader = new StreamReader(stream)) {
|
||||
return Parse(reader);
|
||||
}
|
||||
}
|
||||
|
||||
public ProjectFileDescriptor Parse(TextReader reader) {
|
||||
var document = XDocument.Load(XmlReader.Create(reader));
|
||||
return new ProjectFileDescriptor {
|
||||
AssemblyName = GetAssemblyName(document),
|
||||
SourceFilenames = GetSourceFilenames(document).ToArray(),
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Orchard.Environment.Extensions.Compilers {
|
||||
public interface IProjectFileParser {
|
||||
ProjectFileDescriptor Parse(string virtualPath);
|
||||
ProjectFileDescriptor Parse(Stream stream);
|
||||
}
|
||||
}
|
||||
@@ -299,6 +299,7 @@ namespace Orchard.Environment.Extensions {
|
||||
}
|
||||
|
||||
public void MonitorExtensions(Action<IVolatileToken> monitor) {
|
||||
Logger.Information("Start monitoring extension files...");
|
||||
// Monitor add/remove of any module/theme
|
||||
monitor(_virtualPathMonitor.WhenPathChanges("~/Modules"));
|
||||
monitor(_virtualPathMonitor.WhenPathChanges("~/Themes"));
|
||||
@@ -310,6 +311,7 @@ namespace Orchard.Environment.Extensions {
|
||||
loader.Monitor(extension, monitor);
|
||||
}
|
||||
}
|
||||
Logger.Information("Done monitoring extension files...");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Orchard.Caching;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.FileSystems.WebSite;
|
||||
@@ -12,6 +11,24 @@ using Orchard.Utility.Extensions;
|
||||
|
||||
namespace Orchard.Environment.Extensions.Folders {
|
||||
public class ExtensionFolders : IExtensionFolders {
|
||||
private const string NameSection = "name";
|
||||
private const string PathSection = "path";
|
||||
private const string DescriptionSection = "description";
|
||||
private const string VersionSection = "version";
|
||||
private const string OrchardVersionSection = "orchardversion";
|
||||
private const string AuthorSection = "author";
|
||||
private const string WebsiteSection = "website";
|
||||
private const string TagsSection = "tags";
|
||||
private const string AntiForgerySection = "antiforgery";
|
||||
private const string ZonesSection = "zones";
|
||||
private const string BaseThemeSection = "basetheme";
|
||||
private const string DependenciesSection = "dependencies";
|
||||
private const string CategorySection = "category";
|
||||
private const string FeatureDescriptionSection = "featuredescription";
|
||||
private const string FeatureNameSection = "featurename";
|
||||
private const string PrioritySection = "priority";
|
||||
private const string FeaturesSection = "features";
|
||||
|
||||
private readonly IEnumerable<string> _paths;
|
||||
private readonly string _manifestName;
|
||||
private readonly string _extensionType;
|
||||
@@ -39,48 +56,49 @@ namespace Orchard.Environment.Extensions.Folders {
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public IEnumerable<ExtensionDescriptor> AvailableExtensions() {
|
||||
var list = new List<ExtensionDescriptor>();
|
||||
foreach (var locationPath in _paths) {
|
||||
var path = locationPath;
|
||||
var subList = _cacheManager.Get(locationPath, ctx => {
|
||||
return _paths
|
||||
.SelectMany(path => _cacheManager.Get(path, ctx => {
|
||||
ctx.Monitor(_webSiteFolder.WhenPathChanges(ctx.Key));
|
||||
var subfolderPaths = _webSiteFolder.ListDirectories(ctx.Key);
|
||||
var localList = new List<ExtensionDescriptor>();
|
||||
foreach (var subfolderPath in subfolderPaths) {
|
||||
var extensionId = Path.GetFileName(subfolderPath.TrimEnd('/', '\\'));
|
||||
var manifestPath = Path.Combine(subfolderPath, _manifestName);
|
||||
try {
|
||||
var descriptor = GetExtensionDescriptor(path, extensionId, manifestPath);
|
||||
return AvailableExtensionsInFolder(ctx.Key);
|
||||
}))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
if (descriptor == null)
|
||||
continue;
|
||||
private List<ExtensionDescriptor> AvailableExtensionsInFolder(string path) {
|
||||
Logger.Information("Start looking for extensions in '{0}'...", path);
|
||||
var subfolderPaths = _webSiteFolder.ListDirectories(path);
|
||||
var localList = new List<ExtensionDescriptor>();
|
||||
foreach (var subfolderPath in subfolderPaths) {
|
||||
var extensionId = Path.GetFileName(subfolderPath.TrimEnd('/', '\\'));
|
||||
var manifestPath = Path.Combine(subfolderPath, _manifestName);
|
||||
try {
|
||||
var descriptor = GetExtensionDescriptor(path, extensionId, manifestPath);
|
||||
|
||||
if (descriptor.Path != null && !descriptor.Path.IsValidUrlSegment()) {
|
||||
Logger.Error("The module '{0}' could not be loaded because it has an invalid Path ({1}). It was ignored. The Path if specified must be a valid URL segment. The best bet is to stick with letters and numbers with no spaces.",
|
||||
extensionId,
|
||||
descriptor.Path);
|
||||
continue;
|
||||
}
|
||||
if (descriptor == null)
|
||||
continue;
|
||||
|
||||
if (descriptor.Path == null) {
|
||||
descriptor.Path = descriptor.Name.IsValidUrlSegment()
|
||||
? descriptor.Name
|
||||
: descriptor.Id;
|
||||
}
|
||||
|
||||
localList.Add(descriptor);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Ignore invalid module manifests
|
||||
Logger.Error(ex, "The module '{0}' could not be loaded. It was ignored.", extensionId);
|
||||
}
|
||||
if (descriptor.Path != null && !descriptor.Path.IsValidUrlSegment()) {
|
||||
Logger.Error("The module '{0}' could not be loaded because it has an invalid Path ({1}). It was ignored. The Path if specified must be a valid URL segment. The best bet is to stick with letters and numbers with no spaces.",
|
||||
extensionId,
|
||||
descriptor.Path);
|
||||
continue;
|
||||
}
|
||||
return localList;
|
||||
});
|
||||
list.AddRange(subList);
|
||||
}
|
||||
|
||||
return list;
|
||||
if (descriptor.Path == null) {
|
||||
descriptor.Path = descriptor.Name.IsValidUrlSegment()
|
||||
? descriptor.Name
|
||||
: descriptor.Id;
|
||||
}
|
||||
|
||||
localList.Add(descriptor);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Ignore invalid module manifests
|
||||
Logger.Error(ex, "The module '{0}' could not be loaded. It was ignored.", extensionId);
|
||||
}
|
||||
}
|
||||
Logger.Information("Done looking for extensions in '{0}': {1}", path, string.Join(", ", localList.Select(d => d.Id)));
|
||||
return localList;
|
||||
}
|
||||
|
||||
public static ExtensionDescriptor GetDescriptorForExtension(string locationPath, string extensionId, string extensionType, string manifestText) {
|
||||
@@ -89,17 +107,17 @@ namespace Orchard.Environment.Extensions.Folders {
|
||||
Location = locationPath,
|
||||
Id = extensionId,
|
||||
ExtensionType = extensionType,
|
||||
Name = GetValue(manifest, "Name") ?? extensionId,
|
||||
Path = GetValue(manifest, "Path"),
|
||||
Description = GetValue(manifest, "Description"),
|
||||
Version = GetValue(manifest, "Version"),
|
||||
OrchardVersion = GetValue(manifest, "OrchardVersion"),
|
||||
Author = GetValue(manifest, "Author"),
|
||||
WebSite = GetValue(manifest, "Website"),
|
||||
Tags = GetValue(manifest, "Tags"),
|
||||
AntiForgery = GetValue(manifest, "AntiForgery"),
|
||||
Zones = GetValue(manifest, "Zones"),
|
||||
BaseTheme = GetValue(manifest, "BaseTheme"),
|
||||
Name = GetValue(manifest, NameSection) ?? extensionId,
|
||||
Path = GetValue(manifest, PathSection),
|
||||
Description = GetValue(manifest, DescriptionSection),
|
||||
Version = GetValue(manifest, VersionSection),
|
||||
OrchardVersion = GetValue(manifest, OrchardVersionSection),
|
||||
Author = GetValue(manifest, AuthorSection),
|
||||
WebSite = GetValue(manifest, WebsiteSection),
|
||||
Tags = GetValue(manifest, TagsSection),
|
||||
AntiForgery = GetValue(manifest, AntiForgerySection),
|
||||
Zones = GetValue(manifest, ZonesSection),
|
||||
BaseTheme = GetValue(manifest, BaseThemeSection)
|
||||
};
|
||||
extensionDescriptor.Features = GetFeaturesForExtension(manifest, extensionDescriptor);
|
||||
|
||||
@@ -140,57 +158,57 @@ namespace Orchard.Environment.Extensions.Folders {
|
||||
for (int i = 0; i < fieldLength; i++) {
|
||||
field[i] = field[i].Trim();
|
||||
}
|
||||
switch (field[0]) {
|
||||
case "Name":
|
||||
manifest.Add("Name", field[1]);
|
||||
switch (field[0].ToLowerInvariant()) {
|
||||
case NameSection:
|
||||
manifest.Add(NameSection, field[1]);
|
||||
break;
|
||||
case "Path":
|
||||
manifest.Add("Path", field[1]);
|
||||
case PathSection:
|
||||
manifest.Add(PathSection, field[1]);
|
||||
break;
|
||||
case "Description":
|
||||
manifest.Add("Description", field[1]);
|
||||
case DescriptionSection:
|
||||
manifest.Add(DescriptionSection, field[1]);
|
||||
break;
|
||||
case "Version":
|
||||
manifest.Add("Version", field[1]);
|
||||
case VersionSection:
|
||||
manifest.Add(VersionSection, field[1]);
|
||||
break;
|
||||
case "OrchardVersion":
|
||||
manifest.Add("OrchardVersion", field[1]);
|
||||
case OrchardVersionSection:
|
||||
manifest.Add(OrchardVersionSection, field[1]);
|
||||
break;
|
||||
case "Author":
|
||||
manifest.Add("Author", field[1]);
|
||||
case AuthorSection:
|
||||
manifest.Add(AuthorSection, field[1]);
|
||||
break;
|
||||
case "Website":
|
||||
manifest.Add("Website", field[1]);
|
||||
case WebsiteSection:
|
||||
manifest.Add(WebsiteSection, field[1]);
|
||||
break;
|
||||
case "Tags":
|
||||
manifest.Add("Tags", field[1]);
|
||||
case TagsSection:
|
||||
manifest.Add(TagsSection, field[1]);
|
||||
break;
|
||||
case "AntiForgery":
|
||||
manifest.Add("AntiForgery", field[1]);
|
||||
case AntiForgerySection:
|
||||
manifest.Add(AntiForgerySection, field[1]);
|
||||
break;
|
||||
case "Zones":
|
||||
manifest.Add("Zones", field[1]);
|
||||
case ZonesSection:
|
||||
manifest.Add(ZonesSection, field[1]);
|
||||
break;
|
||||
case "BaseTheme":
|
||||
manifest.Add("BaseTheme", field[1]);
|
||||
case BaseThemeSection:
|
||||
manifest.Add(BaseThemeSection, field[1]);
|
||||
break;
|
||||
case "Dependencies":
|
||||
manifest.Add("Dependencies", field[1]);
|
||||
case DependenciesSection:
|
||||
manifest.Add(DependenciesSection, field[1]);
|
||||
break;
|
||||
case "Category":
|
||||
manifest.Add("Category", field[1]);
|
||||
case CategorySection:
|
||||
manifest.Add(CategorySection, field[1]);
|
||||
break;
|
||||
case "FeatureDescription":
|
||||
manifest.Add("FeatureDescription", field[1]);
|
||||
case FeatureDescriptionSection:
|
||||
manifest.Add(FeatureDescriptionSection, field[1]);
|
||||
break;
|
||||
case "FeatureName":
|
||||
manifest.Add("FeatureName", field[1]);
|
||||
case FeatureNameSection:
|
||||
manifest.Add(FeatureNameSection, field[1]);
|
||||
break;
|
||||
case "Priority":
|
||||
manifest.Add("Priority", field[1]);
|
||||
case PrioritySection:
|
||||
manifest.Add(PrioritySection, field[1]);
|
||||
break;
|
||||
case "Features":
|
||||
manifest.Add("Features", reader.ReadToEnd());
|
||||
case FeaturesSection:
|
||||
manifest.Add(FeaturesSection, reader.ReadToEnd());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -205,18 +223,18 @@ namespace Orchard.Environment.Extensions.Folders {
|
||||
// Default feature
|
||||
FeatureDescriptor defaultFeature = new FeatureDescriptor {
|
||||
Id = extensionDescriptor.Id,
|
||||
Name = GetValue(manifest, "FeatureName") ?? extensionDescriptor.Name,
|
||||
Priority = GetValue(manifest, "Priority") != null ? int.Parse(GetValue(manifest, "Priority")) : 0,
|
||||
Description = GetValue(manifest, "FeatureDescription") ?? GetValue(manifest, "Description") ?? string.Empty,
|
||||
Dependencies = ParseFeatureDependenciesEntry(GetValue(manifest, "Dependencies")),
|
||||
Name = GetValue(manifest, FeatureNameSection) ?? extensionDescriptor.Name,
|
||||
Priority = GetValue(manifest, PrioritySection) != null ? int.Parse(GetValue(manifest, PrioritySection)) : 0,
|
||||
Description = GetValue(manifest, FeatureDescriptionSection) ?? GetValue(manifest, DescriptionSection) ?? string.Empty,
|
||||
Dependencies = ParseFeatureDependenciesEntry(GetValue(manifest, DependenciesSection)),
|
||||
Extension = extensionDescriptor,
|
||||
Category = GetValue(manifest, "Category")
|
||||
Category = GetValue(manifest, CategorySection)
|
||||
};
|
||||
|
||||
featureDescriptors.Add(defaultFeature);
|
||||
|
||||
// Remaining features
|
||||
string featuresText = GetValue(manifest, "Features");
|
||||
string featuresText = GetValue(manifest, FeaturesSection);
|
||||
if (featuresText != null) {
|
||||
FeatureDescriptor featureDescriptor = null;
|
||||
using (StringReader reader = new StringReader(featuresText)) {
|
||||
@@ -253,20 +271,21 @@ namespace Orchard.Environment.Extensions.Folders {
|
||||
for (int i = 0; i < featureFieldLength; i++) {
|
||||
featureField[i] = featureField[i].Trim();
|
||||
}
|
||||
switch (featureField[0]) {
|
||||
case "Name":
|
||||
|
||||
switch (featureField[0].ToLowerInvariant()) {
|
||||
case NameSection:
|
||||
featureDescriptor.Name = featureField[1];
|
||||
break;
|
||||
case "Description":
|
||||
case DescriptionSection:
|
||||
featureDescriptor.Description = featureField[1];
|
||||
break;
|
||||
case "Category":
|
||||
case CategorySection:
|
||||
featureDescriptor.Category = featureField[1];
|
||||
break;
|
||||
case "Priority":
|
||||
case PrioritySection:
|
||||
featureDescriptor.Priority = int.Parse(featureField[1]);
|
||||
break;
|
||||
case "Dependencies":
|
||||
case DependenciesSection:
|
||||
featureDescriptor.Dependencies = ParseFeatureDependenciesEntry(featureField[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -67,14 +67,18 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
}
|
||||
|
||||
public override void Monitor(ExtensionDescriptor descriptor, Action<IVolatileToken> monitor) {
|
||||
if (Disabled)
|
||||
return;
|
||||
|
||||
// Monitor .csproj and all .cs files
|
||||
string projectPath = GetProjectPath(descriptor);
|
||||
if (projectPath != null) {
|
||||
foreach (var path in GetDependencies(projectPath)) {
|
||||
Logger.Information("Monitoring virtual path \"{0}\"", path);
|
||||
Logger.Debug("Monitoring virtual path \"{0}\"", path);
|
||||
|
||||
monitor(_virtualPathMonitor.WhenPathChanges(path));
|
||||
_reloadWorkaround.Monitor(_virtualPathMonitor.WhenPathChanges(path));
|
||||
var token = _virtualPathMonitor.WhenPathChanges(path);
|
||||
monitor(token);
|
||||
_reloadWorkaround.Monitor(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,8 +101,7 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
if (projectPath == null)
|
||||
return Enumerable.Empty<ExtensionReferenceProbeEntry>();
|
||||
|
||||
using (var stream = _virtualPathProvider.OpenFile(projectPath)) {
|
||||
var projectFile = _projectFileParser.Parse(stream);
|
||||
var projectFile = _projectFileParser.Parse(projectPath);
|
||||
|
||||
return projectFile.References.Select(r => new ExtensionReferenceProbeEntry {
|
||||
Descriptor = descriptor,
|
||||
@@ -107,7 +110,6 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
VirtualPath = _virtualPathProvider.GetProjectReferenceVirtualPath(projectPath, r.SimpleName, r.Path)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public override void ReferenceActivated(ExtensionLoadingContext context, ExtensionReferenceProbeEntry referenceEntry) {
|
||||
//Note: This is the same implementation as "PrecompiledExtensionLoader"
|
||||
@@ -165,11 +167,13 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
if (projectPath == null)
|
||||
return null;
|
||||
|
||||
Logger.Information("Start loading dynamic extension \"{0}\"", descriptor.Name);
|
||||
|
||||
var assembly = _buildManager.GetCompiledAssembly(projectPath);
|
||||
if (assembly == null)
|
||||
return null;
|
||||
|
||||
Logger.Information("Loaded dynamic extension \"{0}\": assembly name=\"{1}\"", descriptor.Name, assembly.FullName);
|
||||
Logger.Information("Done loading dynamic extension \"{0}\": assembly name=\"{1}\"", descriptor.Name, assembly.FullName);
|
||||
|
||||
return new ExtensionEntry {
|
||||
Descriptor = descriptor,
|
||||
@@ -179,7 +183,7 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
}
|
||||
|
||||
protected IEnumerable<string> GetDependencies(string projectPath) {
|
||||
HashSet<string> dependencies = new HashSet<string> { projectPath };
|
||||
var dependencies = new HashSet<string> { projectPath };
|
||||
|
||||
AddDependencies(projectPath, dependencies);
|
||||
|
||||
@@ -189,8 +193,7 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
private void AddDependencies(string projectPath, HashSet<string> currentSet) {
|
||||
string basePath = _virtualPathProvider.GetDirectoryName(projectPath);
|
||||
|
||||
using (var stream = _virtualPathProvider.OpenFile(projectPath)) {
|
||||
ProjectFileDescriptor projectFile = _projectFileParser.Parse(stream);
|
||||
ProjectFileDescriptor projectFile = _projectFileParser.Parse(projectPath);
|
||||
|
||||
// Add source files
|
||||
currentSet.UnionWith(projectFile.SourceFilenames.Select(f => _virtualPathProvider.Combine(basePath, f)));
|
||||
@@ -202,6 +205,18 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
? _virtualPathProvider.GetProjectReferenceVirtualPath(projectPath, referenceDescriptor.SimpleName, referenceDescriptor.Path)
|
||||
: _virtualPathProvider.Combine(basePath, referenceDescriptor.Path);
|
||||
|
||||
// Normalize the virtual path (avoid ".." in the path name)
|
||||
if (!string.IsNullOrEmpty(path)) {
|
||||
try {
|
||||
path = _virtualPathProvider.ToAppRelative(path);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// The initial path might have been invalid (e.g. path indicates a path outside the application root)
|
||||
Logger.Information(e, "Path '{0}' cannot be made app relative", path);
|
||||
path = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to reference the project / library file
|
||||
if (!string.IsNullOrEmpty(path) && !currentSet.Contains(path) && _virtualPathProvider.TryFileExists(path)) {
|
||||
currentSet.Add(path);
|
||||
@@ -220,7 +235,6 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string GetProjectPath(ExtensionDescriptor descriptor) {
|
||||
string projectPath = _virtualPathProvider.Combine(descriptor.Location, descriptor.Id,
|
||||
|
||||
@@ -122,10 +122,13 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
}
|
||||
|
||||
public override void Monitor(ExtensionDescriptor descriptor, Action<IVolatileToken> monitor) {
|
||||
if (Disabled)
|
||||
return;
|
||||
|
||||
// If the assembly exists, monitor it
|
||||
string assemblyPath = GetAssemblyPath(descriptor);
|
||||
if (assemblyPath != null) {
|
||||
Logger.Information("Monitoring virtual path \"{0}\"", assemblyPath);
|
||||
Logger.Debug("Monitoring virtual path \"{0}\"", assemblyPath);
|
||||
monitor(_virtualPathMonitor.WhenPathChanges(assemblyPath));
|
||||
return;
|
||||
}
|
||||
@@ -135,7 +138,7 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
// detect that as a change of configuration.
|
||||
var assemblyDirectory = _virtualPathProvider.Combine(descriptor.Location, descriptor.Id, "bin");
|
||||
if (_virtualPathProvider.DirectoryExists(assemblyDirectory)) {
|
||||
Logger.Information("Monitoring virtual path \"{0}\"", assemblyDirectory);
|
||||
Logger.Debug("Monitoring virtual path \"{0}\"", assemblyDirectory);
|
||||
monitor(_virtualPathMonitor.WhenPathChanges(assemblyDirectory));
|
||||
}
|
||||
}
|
||||
@@ -193,11 +196,13 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
if (Disabled)
|
||||
return null;
|
||||
|
||||
Logger.Information("Start loading pre-compiled extension \"{0}\"", descriptor.Name);
|
||||
|
||||
var assembly = _assemblyProbingFolder.LoadAssembly(descriptor.Id);
|
||||
if (assembly == null)
|
||||
return null;
|
||||
|
||||
Logger.Information("Loaded pre-compiled extension \"{0}\": assembly name=\"{1}\"", descriptor.Name, assembly.FullName);
|
||||
Logger.Information("Done loading pre-compiled extension \"{0}\": assembly name=\"{1}\"", descriptor.Name, assembly.FullName);
|
||||
|
||||
return new ExtensionEntry {
|
||||
Descriptor = descriptor,
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace Orchard.Environment.Features {
|
||||
string id = featureId;
|
||||
|
||||
enabledFeatures.Add(new ShellFeature { Name = id });
|
||||
Logger.Information(T("{0} was enabled", featureId).ToString());
|
||||
Logger.Information("{0} was enabled", featureId);
|
||||
}
|
||||
|
||||
_shellDescriptorManager.UpdateShellDescriptor(shellDescriptor.SerialNumber, enabledFeatures,
|
||||
@@ -120,7 +120,7 @@ namespace Orchard.Environment.Features {
|
||||
string id = featureId;
|
||||
|
||||
enabledFeatures.RemoveAll(shellFeature => shellFeature.Name == id);
|
||||
Logger.Information(T("{0} was disabled", featureId).ToString());
|
||||
Logger.Information("{0} was disabled", featureId);
|
||||
}
|
||||
|
||||
_shellDescriptorManager.UpdateShellDescriptor(shellDescriptor.SerialNumber, enabledFeatures,
|
||||
@@ -152,7 +152,7 @@ namespace Orchard.Environment.Features {
|
||||
|
||||
IEnumerable<string> featuresToEnable = GetAffectedFeatures(featureId, availableFeatures, getDisabledDependencies);
|
||||
if (featuresToEnable.Count() > 1 && !force) {
|
||||
Logger.Warning(T("Aditional features need to be enabled.").ToString());
|
||||
Logger.Warning("Additional features need to be enabled.");
|
||||
if (FeatureDependencyNotification != null) {
|
||||
FeatureDependencyNotification("If {0} is enabled, then you'll also need to enable {1}.", featureId, featuresToEnable.Where(fId => fId != featureId));
|
||||
}
|
||||
@@ -178,7 +178,7 @@ namespace Orchard.Environment.Features {
|
||||
|
||||
IEnumerable<string> featuresToDisable = GetAffectedFeatures(featureId, availableFeatures, getEnabledDependants);
|
||||
if (featuresToDisable.Count() > 1 && !force) {
|
||||
Logger.Warning(T("Aditional features need to be disabled.").ToString());
|
||||
Logger.Warning("Additional features need to be disabled.");
|
||||
if (FeatureDependencyNotification != null) {
|
||||
FeatureDependencyNotification("If {0} is disabled, then you'll also need to disable {1}.", featureId, featuresToDisable.Where(fId => fId != featureId));
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.Environment.ShellBuilders.Models;
|
||||
using Orchard.Logging;
|
||||
|
||||
namespace Orchard.Environment.ShellBuilders {
|
||||
/// <summary>
|
||||
@@ -29,9 +30,15 @@ namespace Orchard.Environment.ShellBuilders {
|
||||
|
||||
public CompositionStrategy(IExtensionManager extensionManager) {
|
||||
_extensionManager = extensionManager;
|
||||
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public ShellBlueprint Compose(ShellSettings settings, ShellDescriptor descriptor) {
|
||||
Logger.Debug("Composing blueprint");
|
||||
|
||||
var enabledFeatures = _extensionManager.EnabledFeatures(descriptor);
|
||||
var features = _extensionManager.LoadFeatures(enabledFeatures);
|
||||
|
||||
@@ -43,13 +50,16 @@ namespace Orchard.Environment.ShellBuilders {
|
||||
var controllers = BuildBlueprint(features, IsController, BuildController);
|
||||
var records = BuildBlueprint(features, IsRecord, (t, f) => BuildRecord(t, f, settings));
|
||||
|
||||
return new ShellBlueprint {
|
||||
var result = new ShellBlueprint {
|
||||
Settings = settings,
|
||||
Descriptor = descriptor,
|
||||
Dependencies = dependencies.Concat(modules).ToArray(),
|
||||
Controllers = controllers,
|
||||
Records = records,
|
||||
};
|
||||
|
||||
Logger.Debug("Done composing blueprint");
|
||||
return result;
|
||||
}
|
||||
|
||||
private static IEnumerable<Feature> BuiltinFeatures() {
|
||||
|
||||
@@ -8,6 +8,7 @@ using Orchard.Logging;
|
||||
using Orchard.Services;
|
||||
|
||||
namespace Orchard.FileSystems.VirtualPath {
|
||||
|
||||
public class DefaultVirtualPathMonitor : IVirtualPathMonitor {
|
||||
private readonly Thunk _thunk;
|
||||
private readonly string _prefix = Guid.NewGuid().ToString("n");
|
||||
@@ -23,26 +24,18 @@ namespace Orchard.FileSystems.VirtualPath {
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public IVolatileToken WhenPathChanges(string virtualPath) {
|
||||
var token = BindToken(virtualPath);
|
||||
try {
|
||||
var token = BindToken(virtualPath);
|
||||
|
||||
if (!HostingEnvironment.VirtualPathProvider.DirectoryExists(virtualPath)
|
||||
&& !HostingEnvironment.VirtualPathProvider.FileExists(virtualPath)) {
|
||||
// if trying to monitor a directory or file inside a directory which doesn't exist
|
||||
// monitor first existing parent directory
|
||||
return new Token(virtualPath);
|
||||
}
|
||||
|
||||
BindSignal(virtualPath);
|
||||
return token;
|
||||
}
|
||||
catch (HttpException e) {
|
||||
// This exception happens if trying to monitor a directory or file
|
||||
// inside a directory which doesn't exist
|
||||
Logger.Warning(e, "Error monitor file changes on virtual path '{0}'", virtualPath);
|
||||
// Fix this to monitor first existing parent directory.
|
||||
return new Token(virtualPath);
|
||||
Logger.Warning(e, "Error monitoring file changes on virtual path '{0}'", virtualPath);
|
||||
|
||||
//TODO: Return a token monitoring first existing parent directory.
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
private Token BindToken(string virtualPath) {
|
||||
@@ -81,13 +74,20 @@ namespace Orchard.FileSystems.VirtualPath {
|
||||
}
|
||||
|
||||
private void BindSignal(string virtualPath, CacheItemRemovedCallback callback) {
|
||||
string key = _prefix + virtualPath;
|
||||
|
||||
//PERF: Don't add in the cache if already present. Creating a "CacheDependency"
|
||||
// object (below) is actually quite expensive.
|
||||
if (HostingEnvironment.Cache.Get(key) != null)
|
||||
return;
|
||||
|
||||
var cacheDependency = HostingEnvironment.VirtualPathProvider.GetCacheDependency(
|
||||
virtualPath,
|
||||
new[] { virtualPath },
|
||||
_clock.UtcNow);
|
||||
|
||||
HostingEnvironment.Cache.Add(
|
||||
_prefix + virtualPath,
|
||||
key,
|
||||
virtualPath,
|
||||
cacheDependency,
|
||||
Cache.NoAbsoluteExpiration,
|
||||
|
||||
Reference in New Issue
Block a user