Merge branch '1.10.x' into dev.

This commit is contained in:
Daniel Stolt
2016-06-05 20:51:03 +02:00
23 changed files with 135 additions and 71 deletions

View File

@@ -3,6 +3,7 @@ using Autofac;
using NUnit.Framework;
using Orchard.Localization.Models;
using Orchard.Localization.Services;
using Orchard.Tests.Stubs;
namespace Orchard.Tests.Localization {
@@ -303,10 +304,11 @@ namespace Orchard.Tests.Localization {
}
[Test]
[Description("DST date and time are not properly round-tripped when date is ignored.")]
[Description("DST is ignored when date is ignored (non-DST date).")]
public void ConvertToLocalizedTimeStringTest03() {
var timeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
var container = TestHelpers.InitializeContainer("en-US", null, timeZone);
var clock = new StubClock(new DateTime(2012, 1, 1, 12, 0, 0, DateTimeKind.Utc));
var container = TestHelpers.InitializeContainer("en-US", null, timeZone, clock);
var target = container.Resolve<IDateLocalizationServices>();
var dateString = "3/10/2012";
@@ -318,7 +320,27 @@ namespace Orchard.Tests.Localization {
var timeString2 = target.ConvertToLocalizedTimeString(dateTimeUtc, new DateLocalizationOptions() { IgnoreDate = true });
Assert.AreEqual(dateString, dateString2);
Assert.AreNotEqual(timeString, timeString2);
Assert.AreEqual(timeString, timeString2);
}
[Test]
[Description("DST is ignored when date is ignored (DST date).")]
public void ConvertToLocalizedTimeStringTest04() {
var timeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
var clock = new StubClock(new DateTime(2012, 10, 3, 12, 0, 0, DateTimeKind.Utc));
var container = TestHelpers.InitializeContainer("en-US", null, timeZone, clock);
var target = container.Resolve<IDateLocalizationServices>();
var dateString = "3/10/2012";
var timeString = "12:00:00 PM";
var dateTimeUtc = target.ConvertFromLocalizedString(dateString, timeString);
var dateString2 = target.ConvertToLocalizedDateString(dateTimeUtc);
var timeString2 = target.ConvertToLocalizedTimeString(dateTimeUtc, new DateLocalizationOptions() { IgnoreDate = true });
Assert.AreEqual(dateString, dateString2);
Assert.AreEqual(timeString, timeString2);
}
/*

View File

@@ -9,9 +9,12 @@ using Orchard.Tests.Stubs;
namespace Orchard.Tests.Localization {
internal class TestHelpers {
public static IContainer InitializeContainer(string cultureName, string calendarName, TimeZoneInfo timeZone) {
public static IContainer InitializeContainer(string cultureName, string calendarName, TimeZoneInfo timeZone, IClock clock = null) {
var builder = new ContainerBuilder();
builder.RegisterType<StubClock>().As<IClock>();
if (clock != null)
builder.RegisterInstance(clock);
else
builder.RegisterType<StubClock>().As<IClock>();
builder.RegisterInstance<WorkContext>(new StubWorkContext(cultureName, calendarName, timeZone));
builder.RegisterType<StubWorkContextAccessor>().As<IWorkContextAccessor>();
builder.RegisterType<CultureDateTimeFormatProvider>().As<IDateTimeFormatProvider>();

View File

@@ -4,8 +4,13 @@ using Orchard.Services;
namespace Orchard.Tests.Stubs {
public class StubClock : IClock {
public StubClock() {
UtcNow = new DateTime(2009, 10, 14, 12, 34, 56, DateTimeKind.Utc);
public StubClock()
: this(new DateTime(2009, 10, 14, 12, 34, 56, DateTimeKind.Utc)) {
}
public StubClock(DateTime utcNow) {
UtcNow = utcNow;
}
public DateTime UtcNow { get; private set; }
@@ -18,7 +23,6 @@ namespace Orchard.Tests.Stubs {
return UtcNow.Add(span);
}
public IVolatileToken When(TimeSpan duration) {
return new Clock.AbsoluteExpirationToken(this, duration);
}

File diff suppressed because one or more lines are too long

View File

@@ -130,10 +130,6 @@
<Project>{9916839C-39FC-4CEB-A5AF-89CA7E87119F}</Project>
<Name>Orchard.Core</Name>
</ProjectReference>
<ProjectReference Include="..\Orchard.JobsQueue\Orchard.JobsQueue.csproj">
<Project>{085948ff-0e9b-4a9a-b564-f8b8b4bdddbc}</Project>
<Name>Orchard.JobsQueue</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="Views\Admin\Index.cshtml" />

View File

@@ -47,7 +47,7 @@
handled = true;
}
if (element.type == "Content") { // This is a content element.
if (!!element.hasEditor) { // This element has an editor dialog.
if (!e.ctrlKey && !e.shiftKey && !e.altKey && e.which == 13) { // Enter
$element.find(".layout-panel-action-edit").first().click();
handled = true;

View File

@@ -144,7 +144,7 @@
content: close-quote;
}
br {
br::before {
content: '\A';
white-space: pre;
}

View File

@@ -1,5 +1,6 @@
using Orchard.Environment.Extensions;
using Orchard.Layouts.Framework.Elements;
using Orchard.Localization;
namespace Orchard.Layouts.Elements {
[OrchardFeature("Orchard.Layouts.Snippets")]
@@ -15,5 +16,9 @@ namespace Orchard.Layouts.Elements {
public override bool HasEditor {
get { return false; }
}
public override string ToolboxIcon {
get { return "\uf10c"; }
}
}
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Orchard.DisplayManagement;
using Orchard.DisplayManagement.Descriptors;
using Orchard.Environment;
@@ -63,13 +64,17 @@ namespace Orchard.Layouts.Providers {
var snippetElement = (Snippet)_elementFactory.Value.Activate(elementType);
foreach (var shapeDescriptor in shapeDescriptors) {
var snippetManifest = ParseSnippetManifest(shapeDescriptor.Value.BindingSource);
var shapeType = shapeDescriptor.Value.ShapeType;
var elementName = GetDisplayName(shapeDescriptor.Value.BindingSource);
var elementName = GetDisplayName(snippetManifest, shapeDescriptor.Value.BindingSource);
var toolboxIcon = GetToolboxIcon(snippetManifest, snippetElement);
var description = GetDescription(snippetManifest, shapeType);
var category = GetCategory(snippetManifest, snippetElement);
var closureDescriptor = shapeDescriptor;
var snippetDescriptor = ParseSnippetDescriptor(shapeDescriptor.Value.BindingSource);
yield return new ElementDescriptor(elementType, shapeType, new LocalizedString(elementName), new LocalizedString(String.Format("An element that renders the {0} shape.", shapeType)), snippetElement.Category) {
var snippetDescriptor = ParseSnippetDescriptor(snippetManifest);
yield return new ElementDescriptor(elementType, shapeType, new LocalizedString(elementName), description, category) {
Displaying = displayContext => Displaying(displayContext, closureDescriptor.Value, snippetDescriptor),
ToolboxIcon = "\uf10c",
ToolboxIcon = toolboxIcon,
EnableEditorDialog = snippetDescriptor != null || HasSnippetFields(shapeDescriptor.Value),
Editor = ctx => Editor(snippetDescriptor ?? DescribeSnippet(shapeType, snippetElement), ctx),
UpdateEditor = ctx => UpdateEditor(snippetDescriptor ?? DescribeSnippet(shapeType, snippetElement), ctx)
@@ -132,13 +137,7 @@ namespace Orchard.Layouts.Providers {
context.ElementShape.Snippet = shape;
}
private string GetDisplayName(string bindingSource) {
var fileName = Path.GetFileNameWithoutExtension(bindingSource) ?? "";
var lastIndex = fileName.IndexOf(SnippetShapeSuffix, StringComparison.OrdinalIgnoreCase);
return fileName.Substring(0, lastIndex).CamelFriendly();
}
private SnippetDescriptor ParseSnippetDescriptor(string bindingSource) {
private dynamic ParseSnippetManifest(string bindingSource) {
var physicalSourcePath = _wca.GetContext().HttpContext.Server.MapPath(bindingSource);
var paramsFileName = Path.Combine(Path.GetDirectoryName(physicalSourcePath) ?? "", Path.GetFileNameWithoutExtension(physicalSourcePath) + ".txt");
@@ -147,7 +146,50 @@ namespace Orchard.Layouts.Providers {
var yaml = File.ReadAllText(paramsFileName);
var snippetConfig = Deserialize(yaml);
var fieldsConfig = snippetConfig.Fields != null ? snippetConfig.Fields.Children : new dynamic[0];
return snippetConfig;
}
private string GetDisplayName(dynamic snippetManifest, string bindingSource) {
if (snippetManifest != null && (string)snippetManifest.DisplayName != null) {
return (string)snippetManifest.DisplayName;
}
var fileName = Path.GetFileNameWithoutExtension(bindingSource) ?? "";
var lastIndex = fileName.IndexOf(SnippetShapeSuffix, StringComparison.OrdinalIgnoreCase);
return fileName.Substring(0, lastIndex).CamelFriendly();
}
private string GetToolboxIcon(dynamic snippetManifest, Snippet snippetElement) {
if (snippetManifest != null && (string)snippetManifest.ToolboxIcon != null) {
return Regex.Unescape((string)snippetManifest.ToolboxIcon);
}
return snippetElement.ToolboxIcon;
}
private LocalizedString GetDescription(dynamic snippetManifest, string shapeType) {
if (snippetManifest != null && (string)snippetManifest.Description != null) {
return new LocalizedString((string)snippetManifest.Description);
}
return new LocalizedString(String.Format("An element that renders the {0} shape.", shapeType));
}
private string GetCategory(dynamic snippetManifest, Snippet snippetElement) {
if (snippetManifest != null && (string)snippetManifest.Category != null) {
return (string)snippetManifest.Category;
}
return snippetElement.Category;
}
private SnippetDescriptor ParseSnippetDescriptor(dynamic snippetManifest) {
if(snippetManifest == null || snippetManifest.Fields.Count == 0) {
return null;
}
var fieldsConfig = snippetManifest.Fields.Children;
var descriptor = new SnippetDescriptor();
foreach (var fieldConfig in fieldsConfig) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
@model Orchard.Layouts.ViewModels.EditElementViewModel
@{
ViewBag.Command = "add";
ViewBag.TitleFormat = "Add {0}";
ViewBag.TitleFormat = T("Add {0}").Text;
}
@Html.Partial("ElementEditor", Model, ViewData)

View File

@@ -1,6 +1,6 @@
@model Orchard.Layouts.ViewModels.EditElementViewModel
@{
ViewBag.Command = "update";
ViewBag.TitleFormat = String.IsNullOrWhiteSpace(Model.ElementData) ? "Add {0}" : "Edit {0}";
ViewBag.TitleFormat = String.IsNullOrWhiteSpace(Model.ElementData) ? T("Add {0}").Text : T("Edit {0}").Text;
}
@Html.Partial("ElementEditor", Model, ViewData)

View File

@@ -382,7 +382,7 @@ $(function () {
/* NTFS uses "\" as the directory separator, but AFS uses "/".
Since both of them are illegal characters for file and folder names, it's safe to determine the type of file storage
currently in use based on the directory separator character. */
var separator = deepestChildPath.contains('/') ? '/' : '\\';
var separator = deepestChildPath.indexOf('/') > -1 ? '/' : '\\';
var deepestChildPathBreadCrumbs = deepestChildPath.split(separator);
var currentBreadCrumbs = self.folderPath().split(separator);

View File

@@ -1,11 +0,0 @@
name: MultiTenancy
antiforgery: enabled
author: The Orchard Team
website: http://orchardproject.net
version: 0.5.0
orchardversion: 0.5.0
description: The multi-tenancy module enables multiple Orchard sites to run in isolation inside of a single web application, improving site density on a single server or hosted account.
features:
Orchard.MultiTenancy:
Description: Configure multiple site tenants.
Category: Hosting

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -19,6 +19,7 @@
var description = $(this).find(":selected").data("recipe-description"); // reads the html attribute of the selected option
$("#recipedescription").text(description); // make the contents of <div id="recipe-description"></div> be the escaped description string
});
$("select.recipe").change(); // trigger at page load to bring in sync
$(".data").find('input[name=DatabaseProvider]:checked').click();
});
})(jQuery);

View File

@@ -76,11 +76,11 @@ namespace Orchard.Localization.Services {
public virtual DateTime ConvertFromSiteCalendar(DateTimeParts parts) {
return new DateTime(
parts.Date.Year,
parts.Date.Month,
parts.Date.Month,
parts.Date.Day,
parts.Time.Hour,
parts.Time.Hour,
parts.Time.Minute,
parts.Time.Second,
parts.Time.Second,
parts.Time.Millisecond,
CurrentCalendar,
parts.Time.Kind);
@@ -110,14 +110,15 @@ namespace Orchard.Localization.Services {
if (options.EnableTimeZoneConversion) {
if (options.IgnoreDate) {
// The caller has asked us to ignore the date part and assume it is today. This usually because the source
// is a time-only field, in which case the date part is usually DateTime.MinValue which we should not use
// for the following reasons:
// * DST can be active or not dependeng on the time of the year. We want the conversion to always act as if the time represents today, but we don't want that date stored.
// * Time zone conversion cannot wrap DateTime.MinValue around to the previous day, resulting in undefined result.
// Therefore we convert the date to today's date before the conversion, and back to the original date after.
var today = _clock.UtcNow.Date;
var tempDate = new DateTime(today.Year, today.Month, today.Day, dateValue.Hour, dateValue.Minute, dateValue.Second, dateValue.Millisecond, dateValue.Kind);
// The caller has asked us to ignore the date part. This usually because the source
// is a time-only field. In such cases (with an undefined date) it does not make sense
// to consider DST variations throughout the year, so we will use an arbitrary (but fixed)
// non-DST date for the conversion to ensure DST is never applied during conversion. The
// date part is usually DateTime.MinValue which we should not use because time zone
// conversion cannot wrap DateTime.MinValue around to the previous day, resulting in
// an undefined result. Instead we convert the date to a hard-coded date of 2000-01-01
// before the conversion, and back to the original date after.
var tempDate = new DateTime(2000, 1, 1, dateValue.Hour, dateValue.Minute, dateValue.Second, dateValue.Millisecond, dateValue.Kind);
tempDate = ConvertToSiteTimeZone(tempDate);
dateValue = new DateTime(dateValue.Year, dateValue.Month, dateValue.Day, tempDate.Hour, tempDate.Minute, tempDate.Second, tempDate.Millisecond, tempDate.Kind);
}
@@ -129,7 +130,7 @@ namespace Orchard.Localization.Services {
}
var parts = DateTimeParts.FromDateTime(dateValue, offset);
// INFO: No calendar conversion in this method - we expect the date component to be DateTime.MinValue and irrelevant anyway.
return _dateFormatter.FormatDateTime(parts, _dateTimeFormatProvider.LongTimeFormat);
@@ -201,14 +202,16 @@ namespace Orchard.Localization.Services {
}
if (hasTime && options.EnableTimeZoneConversion) {
// If there is no date component (technically the date component is that of DateTime.MinValue) then
// we must employ some trickery, for two reasons:
// * DST can be active or not dependeng on the time of the year. We want the conversion to always act as if the time represents today, but we don't want that date stored.
// * Time zone conversion cannot wrap DateTime.MinValue around to the previous day, resulting in undefined result.
// Therefore we convert the date to today's date before the conversion, and back to DateTime.MinValue after.
// If there is no date component (technically the date component is that of DateTime.MinValue)
// then we must employ some trickery. With an undefined date it does not make sense
// to consider DST variations throughout the year, so we will use an arbitrary (but fixed)
// non-DST date for the conversion to ensure DST is never applied during conversion. The
// date part is usually DateTime.MinValue which we should not use because time zone
// conversion cannot wrap DateTime.MinValue around to the previous day, resulting in
// an undefined result. Instead we convert the date to a hard-coded date of 2000-01-01
// before the conversion, and back to the original date after.
if (!hasDate) {
var now = _clock.UtcNow;
dateValue = new DateTime(now.Year, now.Month, now.Day, dateValue.Hour, dateValue.Minute, dateValue.Second, dateValue.Millisecond, dateValue.Kind);
dateValue = new DateTime(2000, 1, 1, dateValue.Hour, dateValue.Minute, dateValue.Second, dateValue.Millisecond, dateValue.Kind);
}
dateValue = ConvertFromSiteTimeZone(dateValue);
if (!hasDate) {