--HG--
branch : dev
This commit is contained in:
Sebastien Ros
2010-05-17 15:49:37 -07:00
10 changed files with 80 additions and 177 deletions

View File

@@ -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;

View File

@@ -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");

View File

@@ -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" />

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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>&nbsp;&#124;&nbsp;<%=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><%
}
} %>

View File

@@ -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; }

View File

@@ -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;

View File

@@ -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;
}
}
}