mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 03:25:23 +08:00
Merge
--HG-- branch : dev
This commit is contained in:
@@ -4,6 +4,26 @@ using Orchard.Utility.Extensions;
|
||||
namespace Orchard.Tests.Utility.Extensions {
|
||||
[TestFixture]
|
||||
public class StringExtensionsTests {
|
||||
[Test]
|
||||
public void HtmlClassify_ValidSimpleClassNameReturnsSame() {
|
||||
const string toClassify = "some-class";
|
||||
Assert.That(toClassify.HtmlClassify(), Is.StringMatching("some-class"));
|
||||
}
|
||||
[Test]
|
||||
public void HtmlClassify_SimpleStringReturnsSimpleClassName() {
|
||||
const string toClassify = "this is something";
|
||||
Assert.That(toClassify.HtmlClassify(), Is.StringMatching("this-is-something"));
|
||||
}
|
||||
[Test]
|
||||
public void HtmlClassify_ValidComplexClassNameReturnsSimpleClassName() {
|
||||
const string toClassify = @"some-class\&some.other.class";
|
||||
Assert.That(toClassify.HtmlClassify(), Is.StringMatching("some-class-some-other-class"));
|
||||
}
|
||||
[Test]
|
||||
public void HtmlClassify_CompletelyInvalidClassNameReturnsEmptyString() {
|
||||
const string toClassify = @"0_1234_12";
|
||||
Assert.That(toClassify.HtmlClassify(), Is.StringMatching(""));
|
||||
}
|
||||
[Test]
|
||||
public void OrDefault_ReturnsDefaultForNull() {
|
||||
const string s = null;
|
||||
|
@@ -28,11 +28,11 @@ namespace Orchard.Modules.Controllers {
|
||||
return View(new ModulesIndexViewModel {Modules = modules});
|
||||
}
|
||||
|
||||
public ActionResult Edit(string moduleName) {
|
||||
public ActionResult Edit(string id) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageModules, T("Not allowed to edit module")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var module = _moduleService.GetModuleByName(moduleName);
|
||||
var module = _moduleService.GetModuleByName(id);
|
||||
|
||||
if (module == null)
|
||||
return new NotFoundResult();
|
||||
@@ -51,28 +51,28 @@ namespace Orchard.Modules.Controllers {
|
||||
}
|
||||
|
||||
[ValidateAntiForgeryTokenOrchard]
|
||||
public ActionResult Enable(string featureName) {
|
||||
public ActionResult Enable(string id) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageFeatures, T("Not allowed to manage features")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
if (string.IsNullOrEmpty(featureName))
|
||||
if (string.IsNullOrEmpty(id))
|
||||
return new NotFoundResult();
|
||||
|
||||
_moduleService.EnableFeatures(new [] {featureName});
|
||||
Services.Notifier.Information(T("{0} was enabled", featureName));
|
||||
_moduleService.EnableFeatures(new [] {id});
|
||||
Services.Notifier.Information(T("{0} was enabled", id));
|
||||
|
||||
return RedirectToAction("Features");
|
||||
}
|
||||
|
||||
[ValidateAntiForgeryTokenOrchard]
|
||||
public ActionResult Disable(string featureName) {
|
||||
public ActionResult Disable(string id) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageFeatures, T("Not allowed to manage features")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
if (string.IsNullOrEmpty(featureName))
|
||||
if (string.IsNullOrEmpty(id))
|
||||
return new NotFoundResult();
|
||||
|
||||
_moduleService.DisableFeatures(new[] { featureName });
|
||||
_moduleService.DisableFeatures(new[] { id });
|
||||
//Services.Notifier.Information(T("{0} was disabled", featureName));
|
||||
|
||||
return RedirectToAction("Features");
|
||||
|
@@ -65,13 +65,10 @@
|
||||
<Compile Include="Commands\FeatureCommand.cs" />
|
||||
<Compile Include="Controllers\AdminController.cs" />
|
||||
<Compile Include="Models\ModuleFeature.cs" />
|
||||
<Compile Include="Routing\FeatureNameConstraint.cs" />
|
||||
<Compile Include="ViewModels\FeaturesViewModel.cs" />
|
||||
<Compile Include="Models\Module.cs" />
|
||||
<Compile Include="Permissions.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Routes.cs" />
|
||||
<Compile Include="Routing\ModuleNameConstraint.cs" />
|
||||
<Compile Include="Services\ModuleService.cs" />
|
||||
<Compile Include="ViewModels\ModuleEditViewModel.cs" />
|
||||
<Compile Include="ViewModels\ModulesIndexViewModel.cs" />
|
||||
|
@@ -1,75 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using Orchard.Modules.Routing;
|
||||
using Orchard.Mvc.Routes;
|
||||
|
||||
namespace Orchard.Modules {
|
||||
public class Routes : IRouteProvider {
|
||||
private readonly IModuleNameConstraint _moduleNameConstraint;
|
||||
private readonly IFeatureNameConstraint _featureNameConstraint;
|
||||
|
||||
public Routes(IModuleNameConstraint moduleNameConstraint, IFeatureNameConstraint featureNameConstraint) {
|
||||
_moduleNameConstraint = moduleNameConstraint;
|
||||
_featureNameConstraint = featureNameConstraint;
|
||||
}
|
||||
|
||||
public IEnumerable<RouteDescriptor> GetRoutes() {
|
||||
return new[] {
|
||||
new RouteDescriptor {
|
||||
Route = new Route(
|
||||
"Admin/Modules/Edit/{moduleName}",
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Modules"},
|
||||
{"controller", "Admin"},
|
||||
{"action", "Edit"}
|
||||
},
|
||||
new RouteValueDictionary {
|
||||
{"moduleName", _moduleNameConstraint}
|
||||
},
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Modules"}
|
||||
},
|
||||
new MvcRouteHandler())
|
||||
},
|
||||
new RouteDescriptor {
|
||||
Route = new Route(
|
||||
"Admin/Modules/Enable/{featureName}",
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Modules"},
|
||||
{"controller", "Admin"},
|
||||
{"action", "Enable"}
|
||||
},
|
||||
new RouteValueDictionary {
|
||||
{"featureName", _featureNameConstraint}
|
||||
},
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Modules"}
|
||||
},
|
||||
new MvcRouteHandler())
|
||||
},
|
||||
new RouteDescriptor {
|
||||
Route = new Route(
|
||||
"Admin/Modules/Disable/{featureName}",
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Modules"},
|
||||
{"controller", "Admin"},
|
||||
{"action", "Disable"}
|
||||
},
|
||||
new RouteValueDictionary {
|
||||
{"featureName", _featureNameConstraint}
|
||||
},
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Modules"}
|
||||
},
|
||||
new MvcRouteHandler())
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void GetRoutes(ICollection<RouteDescriptor> routes) {
|
||||
foreach (var routeDescriptor in GetRoutes())
|
||||
routes.Add(routeDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,28 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Routing;
|
||||
|
||||
namespace Orchard.Modules.Routing {
|
||||
public interface IFeatureNameConstraint : IRouteConstraint, ISingletonDependency {
|
||||
}
|
||||
|
||||
public class FeatureNameConstraint : IFeatureNameConstraint {
|
||||
private readonly IModuleService _moduleService;
|
||||
|
||||
public FeatureNameConstraint(IModuleService moduleService) {
|
||||
_moduleService = moduleService;
|
||||
}
|
||||
|
||||
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) {
|
||||
if (routeDirection == RouteDirection.UrlGeneration)
|
||||
return true;
|
||||
|
||||
object value;
|
||||
if (values.TryGetValue(parameterName, out value))
|
||||
return _moduleService.GetModuleByFeatureName(Convert.ToString(value)) != null;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,27 +0,0 @@
|
||||
using System;
|
||||
using System.Web;
|
||||
using System.Web.Routing;
|
||||
|
||||
namespace Orchard.Modules.Routing {
|
||||
public interface IModuleNameConstraint : IRouteConstraint, ISingletonDependency {
|
||||
}
|
||||
|
||||
public class ModuleNameConstraint : IModuleNameConstraint {
|
||||
private readonly IModuleService _moduleService;
|
||||
|
||||
public ModuleNameConstraint(IModuleService moduleService) {
|
||||
_moduleService = moduleService;
|
||||
}
|
||||
|
||||
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) {
|
||||
if (routeDirection == RouteDirection.UrlGeneration)
|
||||
return true;
|
||||
|
||||
object value;
|
||||
if (values.TryGetValue(parameterName, out value))
|
||||
return _moduleService.GetModuleByName(Convert.ToString(value)) != null;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,45 +1,55 @@
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<FeaturesViewModel>" %>
|
||||
<%@ Import Namespace="Orchard.Mvc.Html"%>
|
||||
<%@ Import Namespace="Orchard.Modules.ViewModels"%>
|
||||
<%@ Import Namespace="Orchard.Utility.Extensions" %>
|
||||
<h1><%=Html.TitleForPage(T("Manage Features").ToString()) %></h1>
|
||||
<% if (Model.Features.Count() > 0) { %>
|
||||
<ul class="contentItems"><%
|
||||
<ul class="features"><%
|
||||
var featureGroups = Model.Features.OrderBy(f => f.Descriptor.Category).GroupBy(f => f.Descriptor.Category);
|
||||
foreach (var featureGroup in featureGroups) { %>
|
||||
<li<%=featureGroup == featureGroups.Last() ? " class=\"last\"" : "" %>>
|
||||
<h2><%=Html.Encode(featureGroup.First().Descriptor.Category ?? T("Uncategorized")) %></h2>
|
||||
foreach (var featureGroup in featureGroups) {
|
||||
var categoryName = featureGroup.First().Descriptor.Category ?? T("Uncategorized");
|
||||
var categoryClassName = string.Format("category {0}", Html.Encode(categoryName.ToString().HtmlClassify()));
|
||||
if (featureGroup == featureGroups.First())
|
||||
categoryClassName += " first";
|
||||
if (featureGroup == featureGroups.Last())
|
||||
categoryClassName += " last"; %>
|
||||
<li class="<%=categoryClassName %>">
|
||||
<h2><%=Html.Encode(categoryName) %></h2>
|
||||
<ul><%
|
||||
var features = featureGroup.OrderBy(f => f.Descriptor.Name);
|
||||
foreach (var feature in features) {%>
|
||||
<li<%=feature == features.Last() ? " class=\"last\"" : "" %> id="<%=Html.Encode(feature.Descriptor.Name) %>">
|
||||
foreach (var feature in features) {
|
||||
//hmmm...I feel like I've done this before...
|
||||
var featureId = string.Format("{0} feature", feature.Descriptor.Name).HtmlClassify();
|
||||
var featureClassName = string.Format("feature {0}", feature.IsEnabled ? "enabled" : "disabled");
|
||||
if (feature == features.First())
|
||||
featureClassName += " first";
|
||||
if (feature == features.Last())
|
||||
featureClassName += " last"; %>
|
||||
<li class="<%=featureClassName %>" id="<%=Html.AttributeEncode(featureId) %>">
|
||||
<div class="summary">
|
||||
<div class="properties">
|
||||
<h3><%=Html.Encode(feature.Descriptor.Name) %></h3>
|
||||
<ul class="pageStatus">
|
||||
<li><%
|
||||
//enabled or not
|
||||
if (feature.IsEnabled) { %>
|
||||
<img class="icon" src="<%=ResolveUrl("~/Modules/Orchard.Modules/Content/Admin/images/enabled.gif") %>" alt="<%=_Encoded("Enabled") %>" title="<%=_Encoded("This feature is currently enabled") %>" /><%=_Encoded("Enabled") %><%
|
||||
}
|
||||
else { %>
|
||||
<img class="icon" src="<%=ResolveUrl("~/Modules/Orchard.Modules/Content/Admin/images/disabled.gif") %>" alt="<%=_Encoded("Disabled") %>" title="<%=_Encoded("This feature is currently disabled") %>" /><%=_Encoded("Disabled")%><%
|
||||
} %>
|
||||
</li><%
|
||||
//dependencies
|
||||
if (feature.Descriptor.Dependencies != null && feature.Descriptor.Dependencies.Count() > 0) { %>
|
||||
<li> | <%=T("Depends on: {0}", string.Join(", ", feature.Descriptor.Dependencies.Select(s => Html.Link(Html.Encode(s), string.Format("{0}#{1}", Url.Action("features", new { area = "Orchard.Modules" }), Html.Encode(s)))).OrderBy(s => s).ToArray())) %></li><%
|
||||
} %>
|
||||
</ul>
|
||||
<h3><%=Html.Encode(feature.Descriptor.Name) %></h3><%
|
||||
if (feature.Descriptor.Dependencies != null) { %>
|
||||
<div class="dependencies">
|
||||
<h4><%=_Encoded("Depends on:")%></h4>
|
||||
<%=Html.UnorderedList(
|
||||
feature.Descriptor.Dependencies.OrderBy(s => s),
|
||||
(s, i) => Html.Link(s, string.Format("#{0}", string.Format("{0} feature", s).HtmlClassify())),
|
||||
"",
|
||||
"dependency",
|
||||
"") %>
|
||||
</div><%
|
||||
} %>
|
||||
</div>
|
||||
<div class="related"><%
|
||||
<div class="actions"><%
|
||||
if (feature.IsEnabled) {
|
||||
using (Html.BeginFormAntiForgeryPost(string.Format("{0}#{1}", Url.Action("Disable", new { area = "Orchard.Modules" }), Html.AttributeEncode(feature.Descriptor.Name)), FormMethod.Post, new {@class = "inline link"})) { %>
|
||||
<%=Html.Hidden("featureName", feature.Descriptor.Name) %>
|
||||
using (Html.BeginFormAntiForgeryPost(string.Format("{0}#{1}", Url.Action("Disable", new { area = "Orchard.Modules" }), featureId), FormMethod.Post, new {@class = "inline link"})) { %>
|
||||
<%=Html.Hidden("id", feature.Descriptor.Name, new { id = "" })%>
|
||||
<button type="submit"><%=_Encoded("Disable") %></button><%
|
||||
}
|
||||
} else {
|
||||
using (Html.BeginFormAntiForgeryPost(string.Format("{0}#{1}", Url.Action("Enable", new { area = "Orchard.Modules" }), Html.AttributeEncode(feature.Descriptor.Name)), FormMethod.Post, new {@class = "inline link"})) { %>
|
||||
<%=Html.Hidden("featureName", feature.Descriptor.Name) %>
|
||||
using (Html.BeginFormAntiForgeryPost(string.Format("{0}#{1}", Url.Action("Enable", new { area = "Orchard.Modules" }), featureId), FormMethod.Post, new {@class = "inline link"})) { %>
|
||||
<%=Html.Hidden("id", feature.Descriptor.Name, new { id = "" })%>
|
||||
<button type="submit"><%=_Encoded("Enable") %></button><%
|
||||
}
|
||||
} %>
|
||||
|
@@ -28,7 +28,7 @@ namespace Orchard.Pages.Handlers {
|
||||
Filters.Add(new ActivatingFilter<RoutableAspect>(PageDriver.ContentType.Name));
|
||||
Filters.Add(new ActivatingFilter<BodyAspect>(PageDriver.ContentType.Name));
|
||||
|
||||
OnLoaded<Page>((context, p) => p.ScheduledPublishUtc = _pageService.GetScheduledPublishUtc(p));
|
||||
OnLoaded<Page>((context, page) => page._scheduledPublishUtc.Loader(value => _pageService.GetScheduledPublishUtc(page)));
|
||||
}
|
||||
|
||||
Localizer T { get; set; }
|
||||
|
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Utilities;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Security;
|
||||
|
||||
@@ -52,7 +53,8 @@ namespace Orchard.Pages.Models {
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime? ScheduledPublishUtc { get; set; }
|
||||
public readonly LazyField<DateTime?> _scheduledPublishUtc = new LazyField<DateTime?>();
|
||||
public DateTime? ScheduledPublishUtc { get { return _scheduledPublishUtc.Value; } set{ _scheduledPublishUtc.Value = value;} }
|
||||
|
||||
private string _scheduledPublishUtcDate;
|
||||
|
||||
|
@@ -14,16 +14,20 @@ namespace Orchard.Utility.Extensions {
|
||||
|
||||
return cleanTailRegex.Replace(text.Substring(0, characterCount + 1), "") + ellipsis;
|
||||
}
|
||||
|
||||
public static string HtmlClassify(this string text) {
|
||||
return Regex.Replace(text, @"[^a-zA-Z]+", m => m.Index == 0 ? "" : "-").ToLowerInvariant();
|
||||
}
|
||||
|
||||
public static bool IsNullOrEmptyTrimmed(this string text) {
|
||||
if (text == null) return true;
|
||||
return string.IsNullOrEmpty(text.Trim());
|
||||
return text == null
|
||||
|| string.IsNullOrEmpty(text.Trim());
|
||||
}
|
||||
|
||||
public static string OrDefault(this string text, string defaultValue) {
|
||||
if (string.IsNullOrEmpty(text))
|
||||
return defaultValue;
|
||||
else
|
||||
return text;
|
||||
return string.IsNullOrEmpty(text)
|
||||
? defaultValue
|
||||
: text;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user