Handle local server time and different cultures for PublishLater and ArchiveLater

- Does not include jQuery.datepicker localization, currently forced to en-US parsing

--HG--
branch : dev
This commit is contained in:
Sébastien Ros
2010-10-26 07:56:56 -07:00
parent 278b12f55b
commit c7e49fbfa5
6 changed files with 49 additions and 43 deletions

View File

@@ -5,11 +5,14 @@ using Orchard.ArchiveLater.ViewModels;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers; using Orchard.ContentManagement.Drivers;
using Orchard.Localization; using Orchard.Localization;
using System.Globalization;
namespace Orchard.ArchiveLater.Drivers { namespace Orchard.ArchiveLater.Drivers {
public class ArchiveLaterPartDriver : ContentPartDriver<ArchiveLaterPart> { public class ArchiveLaterPartDriver : ContentPartDriver<ArchiveLaterPart> {
private const string TemplateName = "Parts/ArchiveLater"; private const string TemplateName = "Parts/ArchiveLater";
private readonly IArchiveLaterService _archiveLaterService; private readonly IArchiveLaterService _archiveLaterService;
private const string DatePattern = "M/d/yyyy";
private const string TimePattern = "h:mm tt";
public ArchiveLaterPartDriver( public ArchiveLaterPartDriver(
IOrchardServices services, IOrchardServices services,
@@ -38,8 +41,8 @@ namespace Orchard.ArchiveLater.Drivers {
model.ScheduledArchiveUtc = part.ScheduledArchiveUtc.Value; model.ScheduledArchiveUtc = part.ScheduledArchiveUtc.Value;
model.ArchiveLater = model.ScheduledArchiveUtc.HasValue; model.ArchiveLater = model.ScheduledArchiveUtc.HasValue;
model.ScheduledArchiveDate = model.ScheduledArchiveUtc.HasValue ? model.ScheduledArchiveUtc.Value.ToLocalTime().ToShortDateString() : String.Empty; model.ScheduledArchiveDate = model.ScheduledArchiveUtc.HasValue ? model.ScheduledArchiveUtc.Value.ToLocalTime().ToString(DatePattern, CultureInfo.InvariantCulture) : String.Empty;
model.ScheduledArchiveTime = model.ScheduledArchiveUtc.HasValue ? model.ScheduledArchiveUtc.Value.ToLocalTime().ToShortTimeString() : String.Empty; model.ScheduledArchiveTime = model.ScheduledArchiveUtc.HasValue ? model.ScheduledArchiveUtc.Value.ToLocalTime().ToString(TimePattern, CultureInfo.InvariantCulture) : String.Empty;
return ContentShape("Parts_ArchiveLater_Edit", return ContentShape("Parts_ArchiveLater_Edit",
() => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix)); () => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix));
@@ -51,9 +54,16 @@ namespace Orchard.ArchiveLater.Drivers {
if (updater.TryUpdateModel(model, Prefix, null, null) ) { if (updater.TryUpdateModel(model, Prefix, null, null) ) {
if ( model.ArchiveLater ) { if ( model.ArchiveLater ) {
DateTime scheduled; DateTime scheduled;
if ( DateTime.TryParse(string.Format("{0} {1}", model.ScheduledArchiveDate, model.ScheduledArchiveTime), out scheduled) ) string parseDateTime = String.Concat(model.ScheduledArchiveDate, " ", model.ScheduledArchiveTime);
// 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 scheduled)) {
model.ScheduledArchiveUtc = scheduled.ToUniversalTime(); model.ScheduledArchiveUtc = scheduled.ToUniversalTime();
_archiveLaterService.ArchiveLater(model.ContentItem, model.ScheduledArchiveUtc.HasValue ? model.ScheduledArchiveUtc.Value : DateTime.MaxValue); _archiveLaterService.ArchiveLater(model.ContentItem, model.ScheduledArchiveUtc.HasValue ? model.ScheduledArchiveUtc.Value : DateTime.MaxValue);
}
else {
updater.AddModelError(Prefix, T("{0} is an invalid date and time", parseDateTime));
}
} }
else { else {
_archiveLaterService.RemoveArchiveLaterTasks(model.ContentItem); _archiveLaterService.RemoveArchiveLaterTasks(model.ContentItem);

View File

@@ -6,12 +6,16 @@ using Orchard.PublishLater.Models;
using Orchard.PublishLater.Services; using Orchard.PublishLater.Services;
using Orchard.PublishLater.ViewModels; using Orchard.PublishLater.ViewModels;
using Orchard.Localization; using Orchard.Localization;
using System.Globalization;
using Orchard.Core.Localization.Services;
namespace Orchard.PublishLater.Drivers { namespace Orchard.PublishLater.Drivers {
public class PublishLaterPartDriver : ContentPartDriver<PublishLaterPart> { public class PublishLaterPartDriver : ContentPartDriver<PublishLaterPart> {
private const string TemplateName = "Parts/PublishLater"; private const string TemplateName = "Parts/PublishLater";
private readonly ICommonService _commonService; private readonly ICommonService _commonService;
private readonly IPublishLaterService _publishLaterService; private readonly IPublishLaterService _publishLaterService;
private const string DatePattern = "M/d/yyyy";
private const string TimePattern = "h:mm tt";
public PublishLaterPartDriver( public PublishLaterPartDriver(
IOrchardServices services, IOrchardServices services,
@@ -42,35 +46,43 @@ namespace Orchard.PublishLater.Drivers {
} }
protected override DriverResult Editor(PublishLaterPart part, dynamic shapeHelper) { protected override DriverResult Editor(PublishLaterPart part, dynamic shapeHelper) {
var model = BuildEditorViewModel(part); // date and time are formatted using the same patterns as DateTimePicker is, preventing other cultures issues
var model = new PublishLaterViewModel(part) {
ScheduledPublishUtc = part.ScheduledPublishUtc.Value,
ScheduledPublishDate = part.ScheduledPublishUtc.Value.HasValue ? part.ScheduledPublishUtc.Value.Value.ToLocalTime().ToString(DatePattern, CultureInfo.InvariantCulture) : String.Empty,
ScheduledPublishTime = part.ScheduledPublishUtc.Value.HasValue ? part.ScheduledPublishUtc.Value.Value.ToLocalTime().ToString(TimePattern, CultureInfo.InvariantCulture) : String.Empty
};
return ContentShape("Parts_PublishLater_Edit", return ContentShape("Parts_PublishLater_Edit",
() => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix)); () => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix));
} }
protected override DriverResult Editor(PublishLaterPart part, IUpdateModel updater, dynamic shapeHelper) { protected override DriverResult Editor(PublishLaterPart part, IUpdateModel updater, dynamic shapeHelper) {
var model = new PublishLaterViewModel(part); var model = new PublishLaterViewModel(part);
updater.TryUpdateModel(model, Prefix, null, null); updater.TryUpdateModel(model, Prefix, null, null);
switch (model.Command) { switch (model.Command) {
case "PublishNow": case "PublishNow":
_commonService.Publish(model.ContentItem); _commonService.Publish(model.ContentItem);
//Services.Notifier.Information(T("{0} has been published!", model.ContentItem.TypeDefinition.DisplayName));
break; break;
case "PublishLater": case "PublishLater":
DateTime scheduled; DateTime scheduled;
if (DateTime.TryParse(string.Format("{0} {1}", model.ScheduledPublishUtcDate, model.ScheduledPublishUtcTime), out scheduled)) string parseDateTime = String.Concat(model.ScheduledPublishDate, " ", model.ScheduledPublishTime);
model.ScheduledPublishUtc = scheduled;
_publishLaterService.Publish(model.ContentItem, model.ScheduledPublishUtc.HasValue ? model.ScheduledPublishUtc.Value : DateTime.MaxValue); // use an english culture as it is the one used by jQuery.datepicker by default
//Services.Notifier.Information(T("{0} has been scheduled for publishing!", model.ContentItem.TypeDefinition.DisplayName)); if (DateTime.TryParse(parseDateTime, CultureInfo.GetCultureInfo("en-US"), DateTimeStyles.AssumeLocal, out scheduled)) {
model.ScheduledPublishUtc = part.ScheduledPublishUtc.Value = scheduled.ToUniversalTime();
_publishLaterService.Publish(model.ContentItem, model.ScheduledPublishUtc.Value);
}
else {
updater.AddModelError(Prefix, T("{0} is an invalid date and time", parseDateTime));
}
break; break;
case "SaveDraft": case "SaveDraft":
//Services.Notifier.Information(T("{0} draft has been saved!", model.ContentItem.TypeDefinition.DisplayName));
break; break;
} }
return ContentShape("Parts_PublishLater_Edit", return ContentShape("Parts_PublishLater_Edit",
() => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix)); () => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix));
} }
private static PublishLaterViewModel BuildEditorViewModel(PublishLaterPart part) {
return new PublishLaterViewModel(part);
}
} }
} }

View File

@@ -6,9 +6,9 @@ html.dyn input.hinted {
color:#ccc; color:#ccc;
font-style:italic; font-style:italic;
} }
input#PublishLater_ScheduledPublishUtcDate { input#PublishLater_ScheduledPublishDate {
width:50%; width:50%;
} }
input#PublishLater_ScheduledPublishUtcTime { input#PublishLater_ScheduledPublishTime {
width:36%; width:36%;
} }

View File

@@ -6,8 +6,6 @@ using Orchard.PublishLater.Models;
namespace Orchard.PublishLater.ViewModels { namespace Orchard.PublishLater.ViewModels {
public class PublishLaterViewModel { public class PublishLaterViewModel {
private readonly PublishLaterPart _publishLaterPart; private readonly PublishLaterPart _publishLaterPart;
private string _scheduledPublishUtcTime;
private string _scheduledPublishUtcDate;
public PublishLaterViewModel(PublishLaterPart publishLaterPart) { public PublishLaterViewModel(PublishLaterPart publishLaterPart) {
_publishLaterPart = publishLaterPart; _publishLaterPart = publishLaterPart;
@@ -37,23 +35,8 @@ namespace Orchard.PublishLater.ViewModels {
public DateTime? ScheduledPublishUtc { get; set; } public DateTime? ScheduledPublishUtc { get; set; }
public string ScheduledPublishUtcDate { public string ScheduledPublishDate { get; set; }
get {
return !HasPublished && !string.IsNullOrEmpty(_scheduledPublishUtcDate) || !ScheduledPublishUtc.HasValue
? _scheduledPublishUtcDate
: ScheduledPublishUtc.Value.ToShortDateString();
}
set { _scheduledPublishUtcDate = value; }
}
public string ScheduledPublishTime { get; set; }
public string ScheduledPublishUtcTime {
get {
return !HasPublished && !string.IsNullOrEmpty(_scheduledPublishUtcTime) || !ScheduledPublishUtc.HasValue
? _scheduledPublishUtcTime
: ScheduledPublishUtc.Value.ToShortTimeString();
}
set { _scheduledPublishUtcTime = value; }
}
} }
} }

View File

@@ -21,10 +21,10 @@
<label class="forcheckbox" for="@ViewData.TemplateInfo.GetFullHtmlFieldId("Command_PublishLater")">@T("Publish Later")</label> <label class="forcheckbox" for="@ViewData.TemplateInfo.GetFullHtmlFieldId("Command_PublishLater")">@T("Publish Later")</label>
</div> </div>
<div> <div>
<label class="forpicker" for="@ViewData.TemplateInfo.GetFullHtmlFieldId("ScheduledPublishUtcDate")">@T("Date")</label> <label class="forpicker" for="@ViewData.TemplateInfo.GetFullHtmlFieldId("ScheduledPublishDate")">@T("Date")</label>
@Html.EditorFor(m => m.ScheduledPublishUtcDate) @Html.EditorFor(m => m.ScheduledPublishDate)
<label class="forpicker" for="@ViewData.TemplateInfo.GetFullHtmlFieldId("ScheduledPublishUtcTime")">@T("Time")</label> <label class="forpicker" for="@ViewData.TemplateInfo.GetFullHtmlFieldId("ScheduledPublishTime")">@T("Time")</label>
@Html.EditorFor(m => m.ScheduledPublishUtcTime) @Html.EditorFor(m => m.ScheduledPublishTime)
</div> </div>
</fieldset> </fieldset>
@using(Script.Foot()) { @using(Script.Foot()) {
@@ -43,8 +43,9 @@
.blur(function () { var $this = $(this); setTimeout(function () { if (!$this.val()) { $this.addClass("hinted").val($this.data("hint")) } }, 300) }); .blur(function () { var $this = $(this); setTimeout(function () { if (!$this.val()) { $this.addClass("hinted").val($this.data("hint")) } }, 300) });
} }
}); });
$(@(new HtmlString(string.Format("\"#{0}\"", ViewData.TemplateInfo.GetFullHtmlFieldId("ScheduledPublishUtcDate"))))).datepicker({ showAnim: "" }).focus(function () { $(@(new HtmlString(string.Format("\"#{0}\"", ViewData.TemplateInfo.GetFullHtmlFieldId("Command_PublishLater"))))).attr("checked", "checked") }); $('#@ViewData.TemplateInfo.GetFullHtmlFieldId("ScheduledPublishDate")').datepicker({ showAnim: "" }).focus(function () { $('#@ViewData.TemplateInfo.GetFullHtmlFieldId("Command_PublishLater")').attr("checked", "checked") });
$(@(new HtmlString(string.Format("\"#{0}\"", ViewData.TemplateInfo.GetFullHtmlFieldId("ScheduledPublishUtcTime"))))).timepickr().focus(function () { $(@(new HtmlString(string.Format("\"#{0}\"", ViewData.TemplateInfo.GetFullHtmlFieldId("Command_PublishLater"))))).attr("checked", "checked") }); $('#@ViewData.TemplateInfo.GetFullHtmlFieldId("ScheduledPublishTime")').timepickr().focus(function () { $('#@ViewData.TemplateInfo.GetFullHtmlFieldId("Command_PublishLater")').attr("checked", "checked") });
}) })
//]]> //]]>
</script> </script>

View File

@@ -30,7 +30,7 @@
} }
else { else {
<img class="icon" src="@Href("~/Core/PublishLater/Content/Admin/images/scheduled.gif")" alt="@T("Scheduled")" title="@T("The page is scheduled for publishing")" /><text> @T("Scheduled") </text> <img class="icon" src="@Href("~/Core/PublishLater/Content/Admin/images/scheduled.gif")" alt="@T("Scheduled")" title="@T("The page is scheduled for publishing")" /><text> @T("Scheduled") </text>
@Html.DateTime(((DateTime?)Model.ScheduledPublishUtc).Value, T("M/d/yyyy h:mm tt")) @Html.DateTime(((DateTime?)Model.ScheduledPublishUtc).Value.ToLocalTime(), T("M/d/yyyy h:mm tt"))
}&nbsp;&#124;&nbsp;</li> }&nbsp;&#124;&nbsp;</li>
} }
</ul> </ul>