Merge branch 'dev' into issue/homepage-alias

Conflicts:
	src/Orchard.Web/Modules/Orchard.Autoroute/Drivers/AutoroutePartDriver.cs
	src/Orchard.Web/Modules/Orchard.Autoroute/Handlers/AutoroutePartHandler.cs
	src/Orchard.Web/Modules/Orchard.Autoroute/ImportExport/HomeAliasExportStep.cs
	src/Orchard.Web/Modules/Orchard.Autoroute/Orchard.Autoroute.csproj
	src/Orchard.Web/Modules/Orchard.Autoroute/Services/AutorouteService.cs
	src/Orchard.Web/Modules/Orchard.ImportExport/Views/Admin/ImportResult.cshtml
	src/Orchard.Web/Modules/Orchard.Layouts/Orchard.Layouts.csproj
	src/Orchard.Web/Modules/Orchard.Localization/Providers/LocalizationDateTimeFormatProvider.cs
	src/Orchard.Web/Modules/Orchard.Pages/Orchard.Pages.csproj
	src/Orchard/Localization/Services/CultureDateTimeFormatProvider.cs
	src/Orchard/Localization/Services/DefaultDateFormatter.cs
	src/Orchard/Localization/Services/IDateTimeFormatProvider.cs
This commit is contained in:
Sipke Schoorstra
2015-07-24 14:11:00 +01:00
31 changed files with 578 additions and 568 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,17 +1,17 @@
using Orchard.Localization; using Orchard.Localization;
using Orchard.Security; using Orchard.Security;
using Orchard.UI.Navigation; using Orchard.UI.Navigation;
namespace Orchard.Core.Reports { namespace Orchard.Core.Reports {
public class AdminMenu : INavigationProvider { public class AdminMenu : INavigationProvider {
public Localizer T { get; set; } public Localizer T { get; set; }
public string MenuName { get { return "admin"; } } public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.AddImageSet("reports") builder.AddImageSet("reports")
.Add(T("Reports"), "12", .Add(T("Reports"), "12",
menu => menu.Add(T("View"), "0", item => item.Action("Index", "Admin", new { area = "Reports" }) menu => menu.Add(T("View"), "0", item => item.Action("Index", "Admin", new { area = "Reports" })
.Permission(StandardPermissions.SiteOwner))); .Permission(StandardPermissions.SiteOwner)));
} }
} }
} }

View File

@@ -1,42 +1,42 @@
using System.Linq; using System.Linq;
using System.Web.Mvc; using System.Web.Mvc;
using Orchard.Core.Reports.ViewModels; using Orchard.Core.Reports.ViewModels;
using Orchard.Localization; using Orchard.Localization;
using Orchard.Reports.Services; using Orchard.Reports.Services;
using Orchard.Security; using Orchard.Security;
namespace Orchard.Core.Reports.Controllers { namespace Orchard.Core.Reports.Controllers {
public class AdminController : Controller { public class AdminController : Controller {
private readonly IReportsManager _reportsManager; private readonly IReportsManager _reportsManager;
public AdminController( public AdminController(
IOrchardServices services, IOrchardServices services,
IReportsManager reportsManager) { IReportsManager reportsManager) {
Services = services; Services = services;
_reportsManager = reportsManager; _reportsManager = reportsManager;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
} }
public IOrchardServices Services { get; set; } public IOrchardServices Services { get; set; }
public Localizer T { get; set; } public Localizer T { get; set; }
public ActionResult Index() { public ActionResult Index() {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to list reports"))) if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to list reports")))
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
var model = new ReportsAdminIndexViewModel { Reports = _reportsManager.GetReports().ToList() }; var model = new ReportsAdminIndexViewModel { Reports = _reportsManager.GetReports().ToList() };
return View(model); return View(model);
} }
public ActionResult Display(int id) { public ActionResult Display(int id) {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to display report"))) if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to display report")))
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
var model = new DisplayReportViewModel { Report = _reportsManager.Get(id) }; var model = new DisplayReportViewModel { Report = _reportsManager.Get(id) };
return View(model); return View(model);
} }
} }
} }

View File

@@ -1,9 +1,9 @@
Name: Reports Name: Reports
AntiForgery: enabled AntiForgery: enabled
Author: The Orchard Team Author: The Orchard Team
Website: http://orchardproject.net Website: http://orchardproject.net
Version: 1.9.1 Version: 1.9.1
OrchardVersion: 1.9 OrchardVersion: 1.9
Description: The dashboard module is providing the reports screen of the application. Description: The dashboard module is providing the reports screen of the application.
FeatureDescription: Reports management. FeatureDescription: Reports management.
Category: Core Category: Core

View File

@@ -1,33 +1,33 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Web.Mvc; using System.Web.Mvc;
using System.Web.Routing; using System.Web.Routing;
using Orchard.Mvc.Routes; using Orchard.Mvc.Routes;
namespace Orchard.Core.Reports { namespace Orchard.Core.Reports {
public class Routes : IRouteProvider { public class Routes : IRouteProvider {
public void GetRoutes(ICollection<RouteDescriptor> routes) { public void GetRoutes(ICollection<RouteDescriptor> routes) {
foreach (var routeDescriptor in GetRoutes()) foreach (var routeDescriptor in GetRoutes())
routes.Add(routeDescriptor); routes.Add(routeDescriptor);
} }
public IEnumerable<RouteDescriptor> GetRoutes() { public IEnumerable<RouteDescriptor> GetRoutes() {
return new[] { return new[] {
new RouteDescriptor { new RouteDescriptor {
Priority = -5, Priority = -5,
Route = new Route( Route = new Route(
"Admin/Reports", "Admin/Reports",
new RouteValueDictionary { new RouteValueDictionary {
{"area", "Reports"}, {"area", "Reports"},
{"controller", "Admin"}, {"controller", "Admin"},
{"action", "Index"} {"action", "Index"}
}, },
new RouteValueDictionary(), new RouteValueDictionary(),
new RouteValueDictionary { new RouteValueDictionary {
{"area", "Reports"} {"area", "Reports"}
}, },
new MvcRouteHandler()) new MvcRouteHandler())
} }
}; };
} }
} }
} }

View File

@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<system.webServer> <system.webServer>
<staticContent> <staticContent>
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" /> <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
</staticContent> </staticContent>
<handlers accessPolicy="Script,Read"> <handlers accessPolicy="Script,Read">
<!-- <!--
iis7 - for any request to a file exists on disk, return it via native http module. 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. accessPolicy 'Script' is to allow for a managed 404 page.
--> -->
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule" preCondition="integratedMode" resourceType="File" requireAccess="Read" /> <add name="StaticFile" path="*" verb="*" modules="StaticFileModule" preCondition="integratedMode" resourceType="File" requireAccess="Read" />
</handlers> </handlers>
</system.webServer> </system.webServer>
</configuration> </configuration>

View File

@@ -1,6 +1,6 @@
.navicon-reports { .navicon-reports {
background-image:url(images/menu.reports.png) !important; background-image:url(images/menu.reports.png) !important;
} }
.navicon-reports:hover { .navicon-reports:hover {
background-position:0 -30px !important; background-position:0 -30px !important;
} }

View File

@@ -1,7 +1,7 @@
using Orchard.Reports; using Orchard.Reports;
namespace Orchard.Core.Reports.ViewModels { namespace Orchard.Core.Reports.ViewModels {
public class DisplayReportViewModel { public class DisplayReportViewModel {
public Report Report { get; set; } public Report Report { get; set; }
} }
} }

View File

@@ -1,8 +1,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using Orchard.Reports; using Orchard.Reports;
namespace Orchard.Core.Reports.ViewModels { namespace Orchard.Core.Reports.ViewModels {
public class ReportsAdminIndexViewModel { public class ReportsAdminIndexViewModel {
public IList<Report> Reports { get; set; } public IList<Report> Reports { get; set; }
} }
} }

View File

@@ -1,39 +1,39 @@
@model DisplayReportViewModel @model DisplayReportViewModel
@using Orchard.Core.Reports.ViewModels; @using Orchard.Core.Reports.ViewModels;
@{ Layout.Title = T("Display Report").ToString(); } @{ Layout.Title = T("Display Report").ToString(); }
@using(Html.BeginFormAntiForgeryPost()) { @using(Html.BeginFormAntiForgeryPost()) {
@Html.ValidationSummary() @Html.ValidationSummary()
<fieldset> <fieldset>
<table class="items" summary="@T("This is a table of the reports in your application")"> <table class="items" summary="@T("This is a table of the reports in your application")">
<colgroup> <colgroup>
<col id="Col1" /> <col id="Col1" />
<col id="Col2" /> <col id="Col2" />
<col id="Col3" /> <col id="Col3" />
<col id="Col4" /> <col id="Col4" />
</colgroup> </colgroup>
<thead> <thead>
<tr> <tr>
<th scope="col">@T("Type")</th> <th scope="col">@T("Type")</th>
<th scope="col">@T("Message")</th> <th scope="col">@T("Message")</th>
<th scope="col">@T("Date")</th> <th scope="col">@T("Date")</th>
<th scope="col"></th> <th scope="col"></th>
</tr> </tr>
</thead> </thead>
@foreach (var reportEntry in Model.Report.Entries) { @foreach (var reportEntry in Model.Report.Entries) {
<tr> <tr>
<td> <td>
@reportEntry.Type @reportEntry.Type
</td> </td>
<td> <td>
@reportEntry.Message @reportEntry.Message
</td> </td>
<td> <td>
@reportEntry.Utc.ToLocalTime().ToShortDateString() @reportEntry.Utc.ToLocalTime().ToShortTimeString() @reportEntry.Utc.ToLocalTime().ToShortDateString() @reportEntry.Utc.ToLocalTime().ToShortTimeString()
</td> </td>
</tr> </tr>
} }
</table> </table>
</fieldset> </fieldset>
} }

View File

@@ -1,39 +1,39 @@
@model ReportsAdminIndexViewModel @model ReportsAdminIndexViewModel
@using Orchard.Core.Reports.ViewModels; @using Orchard.Core.Reports.ViewModels;
@{ Layout.Title = T("Reports").ToString(); } @{ Layout.Title = T("Reports").ToString(); }
@using(Html.BeginFormAntiForgeryPost()) { @using(Html.BeginFormAntiForgeryPost()) {
@Html.ValidationSummary() @Html.ValidationSummary()
<fieldset> <fieldset>
<table class="items" summary="@T("This is a table of the reports in your application")"> <table class="items" summary="@T("This is a table of the reports in your application")">
<colgroup> <colgroup>
<col id="Col1" /> <col id="Col1" />
<col id="Col2" /> <col id="Col2" />
<col id="Col3" /> <col id="Col3" />
<col id="Col4" /> <col id="Col4" />
</colgroup> </colgroup>
<thead> <thead>
<tr> <tr>
<th scope="col">@T("Name")</th> <th scope="col">@T("Name")</th>
<th scope="col">@T("Title")</th> <th scope="col">@T("Title")</th>
<th scope="col">@T("Date")</th> <th scope="col">@T("Date")</th>
<th scope="col"></th> <th scope="col"></th>
</tr> </tr>
</thead> </thead>
@foreach (var report in Model.Reports) { @foreach (var report in Model.Reports) {
<tr> <tr>
<td> <td>
@Html.ActionLink(report.ActivityName, "Display", new {id = report.ReportId}) @Html.ActionLink(report.ActivityName, "Display", new {id = report.ReportId})
</td> </td>
<td> <td>
@report.Title @report.Title
</td> </td>
<td> <td>
@report.Utc.ToLocalTime().ToShortDateString() @report.Utc.ToLocalTime().ToShortTimeString() @report.Utc.ToLocalTime().ToShortDateString() @report.Utc.ToLocalTime().ToShortTimeString()
</td> </td>
</tr> </tr>
} }
</table> </table>
</fieldset> </fieldset>
} }

View File

@@ -15,6 +15,12 @@ using Orchard.Localization.Services;
using Orchard.Mvc; using Orchard.Mvc;
using Orchard.Security; using Orchard.Security;
using Orchard.UI.Notify; using Orchard.UI.Notify;
using Orchard.Utility.Extensions;
using Orchard.Localization.Services;
using Orchard.Localization.Models;
using Orchard.Mvc;
using System.Web;
using Orchard.ContentManagement.Aspects;
namespace Orchard.Autoroute.Drivers { namespace Orchard.Autoroute.Drivers {
public class AutoroutePartDriver : ContentPartDriver<AutoroutePart> { public class AutoroutePartDriver : ContentPartDriver<AutoroutePart> {
@@ -56,7 +62,7 @@ namespace Orchard.Autoroute.Drivers {
protected override DriverResult Editor(AutoroutePart part, IUpdateModel updater, dynamic shapeHelper) { protected override DriverResult Editor(AutoroutePart part, IUpdateModel updater, dynamic shapeHelper) {
var settings = part.TypePartDefinition.Settings.GetModel<AutorouteSettings>(); var settings = part.TypePartDefinition.Settings.GetModel<AutorouteSettings>();
var itemCulture = _cultureManager.GetSiteCulture(); var itemCulture = _cultureManager.GetSiteCulture();
// If we are editing an existing content item. // If we are editing an existing content item.
if (part.Record.Id != 0) { if (part.Record.Id != 0) {
ContentItem contentItem = _contentManager.Get(part.Record.ContentItemRecord.Id); ContentItem contentItem = _contentManager.Get(part.Record.ContentItemRecord.Id);

View File

@@ -88,6 +88,30 @@
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Content Include="Module.txt" /> <Content Include="Module.txt" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
<Project>{2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6}</Project>
<Name>Orchard.Framework</Name>
<Private>false</Private>
</ProjectReference>
<ProjectReference Include="..\..\Core\Orchard.Core.csproj">
<Project>{9916839C-39FC-4CEB-A5AF-89CA7E87119F}</Project>
<Name>Orchard.Core</Name>
<Private>false</Private>
</ProjectReference>
<ProjectReference Include="..\Orchard.Alias\Orchard.Alias.csproj">
<Project>{475B6C45-B27C-438B-8966-908B9D6D1077}</Project>
<Name>Orchard.Alias</Name>
</ProjectReference>
<ProjectReference Include="..\Orchard.ContentTypes\Orchard.ContentTypes.csproj">
<Project>{0e7646e8-fe8f-43c1-8799-d97860925ec4}</Project>
<Name>Orchard.ContentTypes</Name>
</ProjectReference>
<ProjectReference Include="..\Orchard.Tokens\Orchard.Tokens.csproj">
<Project>{6F759635-13D7-4E94-BCC9-80445D63F117}</Project>
<Name>Orchard.Tokens</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Commands\AutorouteCommands.cs" /> <Compile Include="Commands\AutorouteCommands.cs" />
<Compile Include="Providers\ContentDefinition\ContentDefinitionEventHandler.cs" /> <Compile Include="Providers\ContentDefinition\ContentDefinitionEventHandler.cs" />
@@ -115,28 +139,7 @@
<Compile Include="Settings\AutorouteSettings.cs" /> <Compile Include="Settings\AutorouteSettings.cs" />
<Compile Include="ViewModels\AutoroutePartEditViewModel.cs" /> <Compile Include="ViewModels\AutoroutePartEditViewModel.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup />
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
<Project>{2d1d92bb-4555-4cbe-8d0e-63563d6ce4c6}</Project>
<Name>Orchard.Framework</Name>
</ProjectReference>
<ProjectReference Include="..\..\Core\Orchard.Core.csproj">
<Project>{9916839c-39fc-4ceb-a5af-89ca7e87119f}</Project>
<Name>Orchard.Core</Name>
</ProjectReference>
<ProjectReference Include="..\Orchard.Alias\Orchard.Alias.csproj">
<Project>{475b6c45-b27c-438b-8966-908b9d6d1077}</Project>
<Name>Orchard.Alias</Name>
</ProjectReference>
<ProjectReference Include="..\Orchard.ContentTypes\Orchard.ContentTypes.csproj">
<Project>{0e7646e8-fe8f-43c1-8799-d97860925ec4}</Project>
<Name>Orchard.ContentTypes</Name>
</ProjectReference>
<ProjectReference Include="..\Orchard.Tokens\Orchard.Tokens.csproj">
<Project>{6f759635-13d7-4e94-bcc9-80445d63f117}</Project>
<Name>Orchard.Tokens</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Placement.info"> <Content Include="Placement.info">
<SubType>Designer</SubType> <SubType>Designer</SubType>
@@ -153,20 +156,20 @@
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" /> <Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild"> <Target Name="BeforeBuild">
</Target> --> </Target> -->
<Target Name="AfterBuild" DependsOnTargets="AfterBuildCompiler"> <Target Name="AfterBuild" DependsOnTargets="AfterBuildCompiler">
<PropertyGroup> <PropertyGroup>
<AreasManifestDir>$(ProjectDir)\..\Manifests</AreasManifestDir> <AreasManifestDir>$(ProjectDir)\..\Manifests</AreasManifestDir>
</PropertyGroup> </PropertyGroup>
<!-- If this is an area child project, uncomment the following line: <!-- If this is an area child project, uncomment the following line:
<CreateAreaManifest AreaName="$(AssemblyName)" AreaType="Child" AreaPath="$(ProjectDir)" ManifestPath="$(AreasManifestDir)" ContentFiles="@(Content)" /> <CreateAreaManifest AreaName="$(AssemblyName)" AreaType="Child" AreaPath="$(ProjectDir)" ManifestPath="$(AreasManifestDir)" ContentFiles="@(Content)" />
--> -->
<!-- If this is an area parent project, uncomment the following lines: <!-- If this is an area parent project, uncomment the following lines:
<CreateAreaManifest AreaName="$(AssemblyName)" AreaType="Parent" AreaPath="$(ProjectDir)" ManifestPath="$(AreasManifestDir)" ContentFiles="@(Content)" /> <CreateAreaManifest AreaName="$(AssemblyName)" AreaType="Parent" AreaPath="$(ProjectDir)" ManifestPath="$(AreasManifestDir)" ContentFiles="@(Content)" />
<CopyAreaManifests ManifestPath="$(AreasManifestDir)" CrossCopy="false" RenameViews="true" /> <CopyAreaManifests ManifestPath="$(AreasManifestDir)" CrossCopy="false" RenameViews="true" />
--> -->
</Target> </Target>
<Target Name="AfterBuildCompiler" Condition="'$(MvcBuildViews)'=='true'"> <Target Name="AfterBuildCompiler" Condition="'$(MvcBuildViews)'=='true'">

View File

@@ -148,8 +148,8 @@ namespace Orchard.Autoroute.Services {
} else { } else {
settings.DefaultPatterns.Add(new DefaultPattern { PatternIndex = "0", Culture = culture }); settings.DefaultPatterns.Add(new DefaultPattern { PatternIndex = "0", Culture = culture });
return new RoutePattern { Name = "Title", Description = "my-title", Pattern = "{Content.Slug}", Culture = culture }; return new RoutePattern { Name = "Title", Description = "my-title", Pattern = "{Content.Slug}", Culture = culture };
}
} }
}
// return a default pattern if set // return a default pattern if set
var patternCultureSearch = settings.Patterns.Any(x => String.Equals(x.Culture, culture, StringComparison.OrdinalIgnoreCase)) ? culture : null; var patternCultureSearch = settings.Patterns.Any(x => String.Equals(x.Culture, culture, StringComparison.OrdinalIgnoreCase)) ? culture : null;
@@ -159,11 +159,11 @@ namespace Orchard.Autoroute.Services {
if (settings.Patterns.Where(x => x.Culture == patternCultureSearch).ElementAt(Convert.ToInt32(settings.DefaultPatterns.Where(x => x.Culture == defaultPatternCultureSearch).FirstOrDefault().PatternIndex)) != null) { if (settings.Patterns.Where(x => x.Culture == patternCultureSearch).ElementAt(Convert.ToInt32(settings.DefaultPatterns.Where(x => x.Culture == defaultPatternCultureSearch).FirstOrDefault().PatternIndex)) != null) {
return settings.Patterns.Where(x => x.Culture == patternCultureSearch).ElementAt(Convert.ToInt32(settings.DefaultPatterns.Where(x => x.Culture == defaultPatternCultureSearch).FirstOrDefault().PatternIndex)); return settings.Patterns.Where(x => x.Culture == patternCultureSearch).ElementAt(Convert.ToInt32(settings.DefaultPatterns.Where(x => x.Culture == defaultPatternCultureSearch).FirstOrDefault().PatternIndex));
}; };
} }
// return a default pattern if none is defined // return a default pattern if none is defined
return new RoutePattern { Name = "Title", Description = "my-title", Pattern = "{Content.Slug}", Culture = culture }; return new RoutePattern { Name = "Title", Description = "my-title", Pattern = "{Content.Slug}", Culture = culture };
} }
public void RemoveAliases(AutoroutePart part) { public void RemoveAliases(AutoroutePart part) {
_aliasService.Delete(part.Path, AliasSource); _aliasService.Delete(part.Path, AliasSource);

View File

@@ -1,6 +1,6 @@
@model Orchard.ImportExport.ViewModels.ImportResultViewModel @model Orchard.ImportExport.ViewModels.ImportResultViewModel
@{ @{
Layout.Title = T("Import Result").ToString(); Layout.Title = T("Import Result").ToString();
} }
@if (Model.Result.IsSuccessful) { @if (Model.Result.IsSuccessful) {
<div class="message message-Information"> <div class="message message-Information">
@@ -14,14 +14,14 @@ else {
} }
<h2>@T("Recipe steps")</h2> <h2>@T("Recipe steps")</h2>
<table class="items" style="width: auto;"> <table class="items" style="width: auto;">
<thead> <thead>
<tr> <tr>
<th>@T("Step")</th> <th>@T("Step")</th>
<th>@T("Executed")</th> <th>@T("Executed")</th>
<th>@T("Result")</th> <th>@T("Result")</th>
<th>@T("Message")</th> <th>@T("Message")</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@foreach (var step in Model.Result.Steps) { @foreach (var step in Model.Result.Steps) {
<tr> <tr>
@@ -30,7 +30,7 @@ else {
<td>@if (step.IsSuccessful) { @T("Successful") } else if (step.IsCompleted) { <strong>@T("Failed")</strong> }</td> <td>@if (step.IsSuccessful) { @T("Successful") } else if (step.IsCompleted) { <strong>@T("Failed")</strong> }</td>
<td><strong>@step.ErrorMessage</strong></td> <td><strong>@step.ErrorMessage</strong></td>
</tr> </tr>
} }
</tbody> </tbody>
</table> </table>

View File

@@ -597,20 +597,20 @@
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" /> <Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild"> <Target Name="BeforeBuild">
</Target> --> </Target> -->
<Target Name="AfterBuild" DependsOnTargets="AfterBuildCompiler"> <Target Name="AfterBuild" DependsOnTargets="AfterBuildCompiler">
<PropertyGroup> <PropertyGroup>
<AreasManifestDir>$(ProjectDir)\..\Manifests</AreasManifestDir> <AreasManifestDir>$(ProjectDir)\..\Manifests</AreasManifestDir>
</PropertyGroup> </PropertyGroup>
<!-- If this is an area child project, uncomment the following line: <!-- If this is an area child project, uncomment the following line:
<CreateAreaManifest AreaName="$(AssemblyName)" AreaType="Child" AreaPath="$(ProjectDir)" ManifestPath="$(AreasManifestDir)" ContentFiles="@(Content)" /> <CreateAreaManifest AreaName="$(AssemblyName)" AreaType="Child" AreaPath="$(ProjectDir)" ManifestPath="$(AreasManifestDir)" ContentFiles="@(Content)" />
--> -->
<!-- If this is an area parent project, uncomment the following lines: <!-- If this is an area parent project, uncomment the following lines:
<CreateAreaManifest AreaName="$(AssemblyName)" AreaType="Parent" AreaPath="$(ProjectDir)" ManifestPath="$(AreasManifestDir)" ContentFiles="@(Content)" /> <CreateAreaManifest AreaName="$(AssemblyName)" AreaType="Parent" AreaPath="$(ProjectDir)" ManifestPath="$(AreasManifestDir)" ContentFiles="@(Content)" />
<CopyAreaManifests ManifestPath="$(AreasManifestDir)" CrossCopy="false" RenameViews="true" /> <CopyAreaManifests ManifestPath="$(AreasManifestDir)" CrossCopy="false" RenameViews="true" />
--> -->
</Target> </Target>
<Target Name="AfterBuildCompiler" Condition="'$(MvcBuildViews)'=='true'"> <Target Name="AfterBuildCompiler" Condition="'$(MvcBuildViews)'=='true'">

View File

@@ -81,6 +81,7 @@
<ProjectReference Include="..\Orchard.Autoroute\Orchard.Autoroute.csproj"> <ProjectReference Include="..\Orchard.Autoroute\Orchard.Autoroute.csproj">
<Project>{66fccd76-2761-47e3-8d11-b45d0001ddaa}</Project> <Project>{66fccd76-2761-47e3-8d11-b45d0001ddaa}</Project>
<Name>Orchard.Autoroute</Name> <Name>Orchard.Autoroute</Name>
<Private>false</Private>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\Orchard.ContentPicker\Orchard.ContentPicker.csproj"> <ProjectReference Include="..\Orchard.ContentPicker\Orchard.ContentPicker.csproj">
<Project>{f301ef7d-f19c-4d83-aa94-cb64f29c037d}</Project> <Project>{f301ef7d-f19c-4d83-aa94-cb64f29c037d}</Project>
@@ -120,11 +121,11 @@
</FlavorProperties> </FlavorProperties>
</VisualStudio> </VisualStudio>
</ProjectExtensions> </ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild"> <Target Name="BeforeBuild">
</Target> </Target>
<Target Name="AfterBuild"> <Target Name="AfterBuild">
</Target> </Target>
--> -->
</Project> </Project>

View File

@@ -1,16 +1,16 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Orchard.Reports { namespace Orchard.Reports {
public class Report { public class Report {
public Report() { public Report() {
Entries = new List<ReportEntry>(); Entries = new List<ReportEntry>();
} }
public IList<ReportEntry> Entries { get; set;} public IList<ReportEntry> Entries { get; set;}
public int ReportId { get; set; } public int ReportId { get; set; }
public string Title { get; set; } public string Title { get; set; }
public string ActivityName { get; set; } public string ActivityName { get; set; }
public DateTime Utc { get; set; } public DateTime Utc { get; set; }
} }
} }

View File

@@ -1,15 +1,15 @@
using System; using System;
namespace Orchard.Reports { namespace Orchard.Reports {
public enum ReportEntryType { public enum ReportEntryType {
Information, Information,
Warning, Warning,
Error Error
} }
public class ReportEntry { public class ReportEntry {
public ReportEntryType Type { get; set; } public ReportEntryType Type { get; set; }
public string Message { get; set; } public string Message { get; set; }
public DateTime Utc { get; set; } public DateTime Utc { get; set; }
} }
} }

View File

@@ -1,35 +1,35 @@
using Orchard.Reports; using Orchard.Reports;
using Orchard.Reports.Services; using Orchard.Reports.Services;
public static class ReportExtentions { public static class ReportExtentions {
/// <summary> /// <summary>
/// Adds a new report entry of type information to a report that was previously registered. /// Adds a new report entry of type information to a report that was previously registered.
/// </summary> /// </summary>
/// <seealso cref="Register()"/> /// <seealso cref="Register()"/>
/// <param name="reportKey">Key, i.e. technical name of the report. Should be the same as the one used when registering the report.</param> /// <param name="reportKey">Key, i.e. technical name of the report. Should be the same as the one used when registering the report.</param>
/// <param name="message">The message to include in the entry.</param> /// <param name="message">The message to include in the entry.</param>
public static void Information(this IReportsCoordinator reportCoordinator, string reportKey, string message) { public static void Information(this IReportsCoordinator reportCoordinator, string reportKey, string message) {
reportCoordinator.Add(reportKey, ReportEntryType.Information, message); reportCoordinator.Add(reportKey, ReportEntryType.Information, message);
} }
/// <summary> /// <summary>
/// Adds a new report entry of type warning to a report that was previously registered. /// Adds a new report entry of type warning to a report that was previously registered.
/// </summary> /// </summary>
/// <seealso cref="Register()"/> /// <seealso cref="Register()"/>
/// <param name="reportKey">Key, i.e. technical name of the report. Should be the same as the one used when registering the report.</param> /// <param name="reportKey">Key, i.e. technical name of the report. Should be the same as the one used when registering the report.</param>
/// <param name="message">The message to include in the entry.</param> /// <param name="message">The message to include in the entry.</param>
public static void Warning(this IReportsCoordinator reportCoordinator, string reportKey, string message) { public static void Warning(this IReportsCoordinator reportCoordinator, string reportKey, string message) {
reportCoordinator.Add(reportKey, ReportEntryType.Warning, message); reportCoordinator.Add(reportKey, ReportEntryType.Warning, message);
} }
/// <summary> /// <summary>
/// Adds a new report entry of type error to a report that was previously registered. /// Adds a new report entry of type error to a report that was previously registered.
/// </summary> /// </summary>
/// <seealso cref="Register()"/> /// <seealso cref="Register()"/>
/// <param name="reportKey">Key, i.e. technical name of the report. Should be the same as the one used when registering the report.</param> /// <param name="reportKey">Key, i.e. technical name of the report. Should be the same as the one used when registering the report.</param>
/// <param name="message">The message to include in the entry.</param> /// <param name="message">The message to include in the entry.</param>
public static void Error(this IReportsCoordinator reportCoordinator, string reportKey, string message) { public static void Error(this IReportsCoordinator reportCoordinator, string reportKey, string message) {
reportCoordinator.Add(reportKey, ReportEntryType.Error, message); reportCoordinator.Add(reportKey, ReportEntryType.Error, message);
} }
} }

View File

@@ -1,30 +1,30 @@
namespace Orchard.Reports.Services { namespace Orchard.Reports.Services {
/// <summary> /// <summary>
/// Exposes a simplified interface for creating reports. Reports provide user-accessible log-like functionality. /// Exposes a simplified interface for creating reports. Reports provide user-accessible log-like functionality.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <see cref="Orchard.Reports.Services.IReportsManager"/> can be used too to create reports directly. /// <see cref="Orchard.Reports.Services.IReportsManager"/> can be used too to create reports directly.
/// </remarks> /// </remarks>
public interface IReportsCoordinator : IDependency { public interface IReportsCoordinator : IDependency {
/// <summary> /// <summary>
/// Adds a new report entry to a report that was previously registered. /// Adds a new report entry to a report that was previously registered.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// Entries can be only added to a report that was previously registered through Register(). /// Entries can be only added to a report that was previously registered through Register().
/// </remarks> /// </remarks>
/// <seealso cref="Register()"/> /// <seealso cref="Register()"/>
/// <param name="reportKey">Key, i.e. technical name of the report. Should be the same as the one used when registering the report.</param> /// <param name="reportKey">Key, i.e. technical name of the report. Should be the same as the one used when registering the report.</param>
/// <param name="type">Type of the entry.</param> /// <param name="type">Type of the entry.</param>
/// <param name="message">The message to include in the entry.</param> /// <param name="message">The message to include in the entry.</param>
void Add(string reportKey, ReportEntryType type, string message); void Add(string reportKey, ReportEntryType type, string message);
/// <summary> /// <summary>
/// Registers a new report so entries can be added to it. /// Registers a new report so entries can be added to it.
/// </summary> /// </summary>
/// <param name="reportKey">Key, i.e. technical name of the report.</param> /// <param name="reportKey">Key, i.e. technical name of the report.</param>
/// <param name="activityName">Name of the activity the report is about (e.g. "Upgrade").</param> /// <param name="activityName">Name of the activity the report is about (e.g. "Upgrade").</param>
/// <param name="title">A title better describing what the report is about (e.g. "Migrating routes of Pages, Blog Posts").</param> /// <param name="title">A title better describing what the report is about (e.g. "Migrating routes of Pages, Blog Posts").</param>
/// <returns>The report's numerical ID.</returns> /// <returns>The report's numerical ID.</returns>
int Register(string reportKey, string activityName, string title); int Register(string reportKey, string activityName, string title);
} }
} }

View File

@@ -1,17 +1,17 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Orchard.Reports.Services { namespace Orchard.Reports.Services {
/// <summary> /// <summary>
/// Service for handling reports. Reports provide user-accessible log-like functionality. /// Service for handling reports. Reports provide user-accessible log-like functionality.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// You can use <see cref="Orchard.Reports.Services.IReportsCoordinator"/> to create reports through a simplified interface. /// You can use <see cref="Orchard.Reports.Services.IReportsCoordinator"/> to create reports through a simplified interface.
/// </remarks> /// </remarks>
public interface IReportsManager : ISingletonDependency { public interface IReportsManager : ISingletonDependency {
void Add(int reportId, ReportEntryType type, string message); void Add(int reportId, ReportEntryType type, string message);
int CreateReport(string title, string activityName); int CreateReport(string title, string activityName);
Report Get(int reportId); Report Get(int reportId);
IEnumerable<Report> GetReports(); IEnumerable<Report> GetReports();
void Flush(); void Flush();
} }
} }

View File

@@ -1,14 +1,14 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Orchard.Reports.Services { namespace Orchard.Reports.Services {
/// <summary> /// <summary>
/// Defines a service that can be used to persist reports. /// Defines a service that can be used to persist reports.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// Implementations of this interface are commonly used from <see cref="Orchard.Reports.Services.IReportsManager"/> implementations. /// Implementations of this interface are commonly used from <see cref="Orchard.Reports.Services.IReportsManager"/> implementations.
/// </remarks> /// </remarks>
public interface IReportsPersister : IDependency { public interface IReportsPersister : IDependency {
IEnumerable<Report> Fetch(); IEnumerable<Report> Fetch();
void Save(IEnumerable<Report> reports); void Save(IEnumerable<Report> reports);
} }
} }

View File

@@ -1,36 +1,36 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Orchard.Logging; using Orchard.Logging;
namespace Orchard.Reports.Services { namespace Orchard.Reports.Services {
public class ReportsCoordinator : IReportsCoordinator, IDisposable { public class ReportsCoordinator : IReportsCoordinator, IDisposable {
private readonly IReportsManager _reportsManager; private readonly IReportsManager _reportsManager;
private readonly IDictionary<string, int> _reports; private readonly IDictionary<string, int> _reports;
public ReportsCoordinator(IReportsManager reportsManager) { public ReportsCoordinator(IReportsManager reportsManager) {
_reportsManager = reportsManager; _reportsManager = reportsManager;
Logger = NullLogger.Instance; Logger = NullLogger.Instance;
_reports = new Dictionary<string, int>(); _reports = new Dictionary<string, int>();
} }
public ILogger Logger { get; set; } public ILogger Logger { get; set; }
public void Dispose() { public void Dispose() {
_reportsManager.Flush(); _reportsManager.Flush();
} }
public void Add(string reportKey, ReportEntryType type, string message) { public void Add(string reportKey, ReportEntryType type, string message) {
if(!_reports.ContainsKey(reportKey)) { if(!_reports.ContainsKey(reportKey)) {
// ignore message if no corresponding report // ignore message if no corresponding report
return; return;
} }
_reportsManager.Add(_reports[reportKey], type, message); _reportsManager.Add(_reports[reportKey], type, message);
} }
public int Register(string reportKey, string activityName, string title) { public int Register(string reportKey, string activityName, string title) {
int reportId = _reportsManager.CreateReport(title, activityName); int reportId = _reportsManager.CreateReport(title, activityName);
_reports.Add(reportKey, reportId); _reports.Add(reportKey, reportId);
return reportId; return reportId;
} }
} }
} }

View File

@@ -1,74 +1,74 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Orchard.Logging; using Orchard.Logging;
namespace Orchard.Reports.Services { namespace Orchard.Reports.Services {
public class ReportsManager : IReportsManager { public class ReportsManager : IReportsManager {
private readonly IReportsPersister _reportsPersister; private readonly IReportsPersister _reportsPersister;
private List<Report> _reports; private List<Report> _reports;
private static readonly object _synLock = new object(); private static readonly object _synLock = new object();
private bool _isDirty; private bool _isDirty;
public ReportsManager(IReportsPersister reportsPersister) { public ReportsManager(IReportsPersister reportsPersister) {
_reportsPersister = reportsPersister; _reportsPersister = reportsPersister;
Logger = NullLogger.Instance; Logger = NullLogger.Instance;
} }
public ILogger Logger { get; set; } public ILogger Logger { get; set; }
public void Add(int reportId, ReportEntryType type, string message) { public void Add(int reportId, ReportEntryType type, string message) {
lock ( _synLock ) { lock ( _synLock ) {
LoadReports(); LoadReports();
_isDirty = true; _isDirty = true;
var report = Get(reportId); var report = Get(reportId);
if(report == null) { if(report == null) {
return; return;
} }
report.Entries.Add(new ReportEntry {Message = message, Type = type, Utc = DateTime.UtcNow}); report.Entries.Add(new ReportEntry {Message = message, Type = type, Utc = DateTime.UtcNow});
} }
} }
public int CreateReport(string title, string activityName) { public int CreateReport(string title, string activityName) {
lock ( _synLock ) { lock ( _synLock ) {
LoadReports(); LoadReports();
_isDirty = true; _isDirty = true;
var reportId = _reports.Count == 0 ? 1 : _reports.Max(r => r.ReportId) + 1; var reportId = _reports.Count == 0 ? 1 : _reports.Max(r => r.ReportId) + 1;
var report = new Report {ActivityName = activityName, ReportId = reportId, Title = title, Utc = DateTime.UtcNow}; var report = new Report {ActivityName = activityName, ReportId = reportId, Title = title, Utc = DateTime.UtcNow};
_reports.Add(report); _reports.Add(report);
return reportId; return reportId;
} }
} }
public Report Get(int reportId) { public Report Get(int reportId) {
lock(_synLock) { lock(_synLock) {
LoadReports(); LoadReports();
return _reports.Where(r => r.ReportId == reportId).FirstOrDefault(); return _reports.Where(r => r.ReportId == reportId).FirstOrDefault();
} }
} }
public IEnumerable<Report> GetReports() { public IEnumerable<Report> GetReports() {
lock ( _synLock ) { lock ( _synLock ) {
LoadReports(); LoadReports();
return _reports.ToList(); return _reports.ToList();
} }
} }
public void Flush() { public void Flush() {
if ( _reports == null || !_isDirty) { if ( _reports == null || !_isDirty) {
return; return;
} }
lock ( _synLock ) { lock ( _synLock ) {
_reportsPersister.Save(_reports); _reportsPersister.Save(_reports);
_isDirty = false; _isDirty = false;
} }
} }
private void LoadReports() { private void LoadReports() {
if(_reports == null) { if(_reports == null) {
_reports = _reportsPersister.Fetch().ToList(); _reports = _reportsPersister.Fetch().ToList();
} }
} }
} }
} }

View File

@@ -1,67 +1,67 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using System.Xml; using System.Xml;
using System.Xml.Linq; using System.Xml.Linq;
using Orchard.Environment.Configuration; using Orchard.Environment.Configuration;
using Orchard.FileSystems.AppData; using Orchard.FileSystems.AppData;
using System.IO; using System.IO;
namespace Orchard.Reports.Services { namespace Orchard.Reports.Services {
public class ReportsPersister : IReportsPersister { public class ReportsPersister : IReportsPersister {
private readonly IAppDataFolder _appDataFolder; private readonly IAppDataFolder _appDataFolder;
private readonly ShellSettings _shellSettings; private readonly ShellSettings _shellSettings;
private readonly string _reportsFileName; private readonly string _reportsFileName;
private readonly DataContractSerializer _dataContractSerializer; private readonly DataContractSerializer _dataContractSerializer;
private readonly object _synLock = new object(); private readonly object _synLock = new object();
public ReportsPersister(IAppDataFolder appDataFolder, ShellSettings shellSettings) { public ReportsPersister(IAppDataFolder appDataFolder, ShellSettings shellSettings) {
_appDataFolder = appDataFolder; _appDataFolder = appDataFolder;
_shellSettings = shellSettings; _shellSettings = shellSettings;
_dataContractSerializer = new DataContractSerializer(typeof(Report), new [] { typeof(ReportEntry) }); _dataContractSerializer = new DataContractSerializer(typeof(Report), new [] { typeof(ReportEntry) });
_reportsFileName = Path.Combine(Path.Combine("Sites", _shellSettings.Name), "reports.dat"); _reportsFileName = Path.Combine(Path.Combine("Sites", _shellSettings.Name), "reports.dat");
} }
public IEnumerable<Report> Fetch() { public IEnumerable<Report> Fetch() {
lock ( _synLock ) { lock ( _synLock ) {
if ( !_appDataFolder.FileExists(_reportsFileName) ) { if ( !_appDataFolder.FileExists(_reportsFileName) ) {
yield break; yield break;
} }
var text = _appDataFolder.ReadFile(_reportsFileName); var text = _appDataFolder.ReadFile(_reportsFileName);
var xmlDocument = XDocument.Parse(text); var xmlDocument = XDocument.Parse(text);
var rootNode = xmlDocument.Root; var rootNode = xmlDocument.Root;
if (rootNode == null) { if (rootNode == null) {
yield break; yield break;
} }
foreach (var reportNode in rootNode.Elements()) { foreach (var reportNode in rootNode.Elements()) {
var reader = new StringReader(reportNode.Value); var reader = new StringReader(reportNode.Value);
using (var xmlReader = XmlReader.Create(reader)) { using (var xmlReader = XmlReader.Create(reader)) {
yield return (Report) _dataContractSerializer.ReadObject(xmlReader, true); yield return (Report) _dataContractSerializer.ReadObject(xmlReader, true);
} }
} }
} }
} }
public void Save(IEnumerable<Report> reports) { public void Save(IEnumerable<Report> reports) {
lock ( _synLock ) { lock ( _synLock ) {
var xmlDocument = new XDocument(); var xmlDocument = new XDocument();
xmlDocument.Add(new XElement("Reports")); xmlDocument.Add(new XElement("Reports"));
foreach (var report in reports) { foreach (var report in reports) {
var reportNode = new XElement("Report"); var reportNode = new XElement("Report");
var writer = new StringWriter(); var writer = new StringWriter();
using (var xmlWriter = XmlWriter.Create(writer)) { using (var xmlWriter = XmlWriter.Create(writer)) {
_dataContractSerializer.WriteObject(xmlWriter, report); _dataContractSerializer.WriteObject(xmlWriter, report);
} }
reportNode.Value = writer.ToString(); reportNode.Value = writer.ToString();
xmlDocument.Root.Add(reportNode); xmlDocument.Root.Add(reportNode);
} }
var saveWriter = new StringWriter(); var saveWriter = new StringWriter();
xmlDocument.Save(saveWriter); xmlDocument.Save(saveWriter);
_appDataFolder.CreateFile(_reportsFileName, saveWriter.ToString()); _appDataFolder.CreateFile(_reportsFileName, saveWriter.ToString());
} }
} }
} }
} }