--HG--
branch : dev
This commit is contained in:
Dave Reed
2010-10-14 17:36:58 -07:00
21 changed files with 108 additions and 93 deletions

View File

@@ -84,6 +84,13 @@ namespace Orchard.Core.Tests.Routable.Services {
Assert.That(_routableService.IsSlugValid("some/page"), Is.True);
}
[Test]
public void DotsAroundSlugAreAllowed() {
Assert.That(_routableService.IsSlugValid(".slug"), Is.False);
Assert.That(_routableService.IsSlugValid("slug."), Is.False);
Assert.That(_routableService.IsSlugValid("slug.slug"), Is.True);
}
[Test]
public void EmptySlugsShouldBeConsideredValid() {
// so that automatic generation on Publish occurs

View File

@@ -198,7 +198,7 @@ namespace Orchard.Core.Contents.Controllers {
ActionResult CreatableTypeList() {
var list = Shape.List();
list.AddRange(GetCreatableTypes());
list.AddRange("CreatableTypeList", GetCreatableTypes());
var viewModel = Shape.ViewModel()
.ContentTypes(list);

View File

@@ -82,8 +82,14 @@ namespace Orchard.Core.Routable.Drivers {
part.Title = model.Title;
part.Slug = model.Slug;
if (!_routableService.IsSlugValid(part.Slug)) {
updater.AddModelError("Routable.Slug", T("Please do not use any of the following characters in your slugs: \":\", \"?\", \"#\", \"[\", \"]\", \"@\", \"!\", \"$\", \"&\", \"'\", \"(\", \")\", \"*\", \"+\", \",\", \";\", \"=\". No spaces are allowed (please use dashes or underscores instead)."));
if ( !_routableService.IsSlugValid(part.Slug) ) {
var slug = (part.Slug ?? String.Empty);
if ( slug.StartsWith(".") || slug.EndsWith(".") ) {
updater.AddModelError("Routable.Slug", T("The \".\" can't be used around routes."));
}
else {
updater.AddModelError("Routable.Slug", T("Please do not use any of the following characters in your slugs: \":\", \"?\", \"#\", \"[\", \"]\", \"@\", \"!\", \"$\", \"&\", \"'\", \"(\", \")\", \"*\", \"+\", \",\", \";\", \"=\". No spaces are allowed (please use dashes or underscores instead)."));
}
}
string originalSlug = part.Slug;

View File

@@ -26,6 +26,9 @@ namespace Orchard.Core.Routable.Services {
if (slug.Length > 1000)
slug = slug.Substring(0, 1000);
// dots are not allowed at the begin and the end of routes
slug = slug.Trim('.');
model.Slug = slug.ToLowerInvariant();
}
@@ -63,8 +66,7 @@ namespace Orchard.Core.Routable.Services {
}
public bool IsSlugValid(string slug) {
// see http://tools.ietf.org/html/rfc3987 for prohibited chars
return slug == null || String.IsNullOrEmpty(slug.Trim()) || Regex.IsMatch(slug, @"^[^:?#\[\]@!$&'()*+,;=\s]+$");
return String.IsNullOrWhiteSpace(slug) || Regex.IsMatch(slug, @"^[^:?#\[\]@!$&'()*+,;=\s]+$") && !(slug.StartsWith(".") || slug.EndsWith("."));
}
public bool ProcessSlug(RoutePart part) {
@@ -80,7 +82,6 @@ namespace Orchard.Core.Routable.Services {
// of slugs to consider for conflict detection
pathsLikeThis = pathsLikeThis.Where(p => p.ContentItem.Id != part.ContentItem.Id);
//todo: (heskew) need better messages
if (pathsLikeThis.Count() > 0) {
var originalSlug = part.Slug;
//todo: (heskew) make auto-uniqueness optional

View File

@@ -43,7 +43,6 @@ namespace Orchard.Blogs.Controllers {
public IOrchardServices Services { get; set; }
public ActionResult Create() {
//TODO: (erikpo) Might think about moving this to an ActionFilter/Attribute
if (!Services.Authorizer.Authorize(Permissions.ManageBlogs, T("Not allowed to create blogs")))
return new HttpUnauthorizedResult();
@@ -57,7 +56,6 @@ namespace Orchard.Blogs.Controllers {
[HttpPost, ActionName("Create")]
public ActionResult CreatePOST() {
//TODO: (erikpo) Might think about moving this to an ActionFilter/Attribute
if (!Services.Authorizer.Authorize(Permissions.ManageBlogs, T("Couldn't create blog")))
return new HttpUnauthorizedResult();
@@ -79,7 +77,6 @@ namespace Orchard.Blogs.Controllers {
}
public ActionResult Edit(string blogSlug) {
//TODO: (erikpo) Might think about moving this to an ActionFilter/Attribute
if (!Services.Authorizer.Authorize(Permissions.ManageBlogs, T("Not allowed to edit blog")))
return new HttpUnauthorizedResult();
@@ -93,7 +90,6 @@ namespace Orchard.Blogs.Controllers {
[HttpPost, ActionName("Edit")]
public ActionResult EditPOST(string blogSlug) {
//TODO: (erikpo) Might think about moving this to an ActionFilter/Attribute
if (!Services.Authorizer.Authorize(Permissions.ManageBlogs, T("Couldn't edit blog")))
return new HttpUnauthorizedResult();
@@ -112,7 +108,6 @@ namespace Orchard.Blogs.Controllers {
[HttpPost]
public ActionResult Remove(string blogSlug) {
//TODO: (erikpo) Might think about moving this to an ActionFilter/Attribute
if (!Services.Authorizer.Authorize(Permissions.ManageBlogs, T("Couldn't delete blog")))
return new HttpUnauthorizedResult();

View File

@@ -18,21 +18,21 @@ namespace Orchard.Blogs.Handlers {
private static void RecalculateBlogArchive(IRepository<BlogPartArchiveRecord> blogArchiveRepository, IRepository<CommonPartRecord> commonRepository, BlogPostPart blogPostPart) {
blogArchiveRepository.Flush();
//INFO: (erikpo) Remove all current blog archive records
// remove all current blog archive records
var blogArchiveRecords =
from bar in blogArchiveRepository.Table
where bar.BlogPart == blogPostPart.BlogPart.Record
select bar;
blogArchiveRecords.ToList().ForEach(blogArchiveRepository.Delete);
//INFO: (erikpo) Get all blog posts for the current blog
// get all blog posts for the current blog
var postsQuery =
from bpr in commonRepository.Table
where bpr.ContentItemRecord.ContentType.Name == "BlogPost" && bpr.Container.Id == blogPostPart.BlogPart.Record.Id
orderby bpr.PublishedUtc
select bpr;
//INFO: (erikpo) Create a dictionary of all the year/month combinations and their count of posts that are published in this blog
// create a dictionary of all the year/month combinations and their count of posts that are published in this blog
var inMemoryBlogArchives = new Dictionary<DateTime, int>(postsQuery.Count());
foreach (var post in postsQuery) {
if (!post.PublishedUtc.HasValue)
@@ -46,7 +46,7 @@ namespace Orchard.Blogs.Handlers {
inMemoryBlogArchives[key] = 1;
}
//INFO: (erikpo) Create the new blog archive records based on the in memory values
// create the new blog archive records based on the in memory values
foreach (KeyValuePair<DateTime, int> item in inMemoryBlogArchives) {
blogArchiveRepository.Create(new BlogPartArchiveRecord {BlogPart = blogPostPart.BlogPart.Record, Year = item.Key.Year, Month = item.Key.Month, PostCount = item.Value});
}

View File

@@ -9,7 +9,6 @@ namespace Orchard.Blogs.Models {
set { this.As<RoutePart>().Title = value; }
}
//TODO: (erikpo) Need a data type for slug
public string Slug {
get { return this.As<RoutePart>().Slug; }
set { this.As<RoutePart>().Slug = value; }

View File

@@ -27,7 +27,7 @@ namespace Orchard.ContentTypes.Controllers {
#region Types
public ActionResult List() {
return View(new ListContentTypesViewModel {
return View("List", new ListContentTypesViewModel {
Types = _contentDefinitionService.GetTypes()
});
}

View File

@@ -22,7 +22,7 @@ namespace Orchard.Experimental.Controllers {
}
public ActionResult Execute() {
return View(new CommandsExecuteViewModel());
return View("Execute", new CommandsExecuteViewModel());
}
[HttpPost]

View File

@@ -59,7 +59,6 @@
</ItemGroup>
<ItemGroup>
<Compile Include="AdminMenu.cs" />
<Compile Include="ResourceManifest.cs" />
<Compile Include="Commands\IndexingCommands.cs" />
<Compile Include="Controllers\AdminController.cs" />
<Compile Include="Migrations.cs" />
@@ -100,6 +99,7 @@
<Content Include="Views\DefinitionTemplates\FieldIndexing.cshtml" />
<Content Include="Views\DefinitionTemplates\TypeIndexing.cshtml" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
<ProjectExtensions>

View File

@@ -1,13 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Orchard.UI.Resources;
namespace Orchard.Indexing {
public class ResourceManifest : IResourceManifestProvider {
public void BuildManifests(ResourceManifestBuilder builder) {
builder.Add().DefineStyle("IndexingAdmin").SetUrl("admin.css"); // todo: this does not exist
}
}
}

View File

@@ -1,5 +1,4 @@
@model Orchard.Indexing.ViewModels.IndexViewModel
@{ Style.Require("IndexingAdmin"); }
<h1>@Html.TitleForPage(T("Search Index Management").ToString())</h1>
@using (Html.BeginForm("update", "admin", FormMethod.Post, new {area = "Orchard.Indexing"})) {

View File

@@ -107,7 +107,7 @@ namespace Orchard.Packaging.Controllers {
public ActionResult Modules(Guid? sourceId) {
var selectedSource = _packagingSourceManager.GetSources().Where(s => s.Id == sourceId).FirstOrDefault();
return View(new PackagingModulesViewModel {
return View("Modules", new PackagingModulesViewModel {
Modules = _packagingSourceManager.GetModuleList(selectedSource).Where(p => p.SyndicationItem.Categories.All(c => c.Name == "Orchard Module" || c.Name != "Orchard Theme")),
Sources = _packagingSourceManager.GetSources().OrderBy(s => s.FeedTitle),
SelectedSource = selectedSource
@@ -117,7 +117,7 @@ namespace Orchard.Packaging.Controllers {
public ActionResult Themes(Guid? sourceId) {
var selectedSource = _packagingSourceManager.GetSources().Where(s => s.Id == sourceId).FirstOrDefault();
return View(new PackagingModulesViewModel {
return View("Themes", new PackagingModulesViewModel {
Modules = _packagingSourceManager.GetModuleList(selectedSource).Where(p => p.SyndicationItem.Categories.Any(c => c.Name == "Orchard Theme")),
Sources = _packagingSourceManager.GetSources().OrderBy(s => s.FeedTitle),
SelectedSource = selectedSource

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Orchard.Core.Contents.Controllers;
using Orchard.Localization;
using Orchard.Roles.Models;
using Orchard.Roles.Services;
@@ -98,9 +99,9 @@ namespace Orchard.Roles.Controllers {
var role = _roleService.GetRole(id);
if (role == null) {
//TODO: Error message
throw new HttpException(404, "page with id " + id + " was not found");
return HttpNotFound();
}
var model = new RoleEditViewModel { Name = role.Name, Id = role.Id,
RoleCategoryPermissions = _roleService.GetInstalledPermissions(),
CurrentPermissions = _roleService.GetPermissionsForRole(id)};
@@ -117,7 +118,8 @@ namespace Orchard.Roles.Controllers {
}
[HttpPost, ActionName("Edit")]
public ActionResult EditPOST() {
[FormValueRequired("submit.Save")]
public ActionResult EditSavePOST(int id) {
if (!Services.Authorizer.Authorize(Permissions.ManageRoles, T("Not authorized to manage roles")))
return new HttpUnauthorizedResult();
@@ -125,24 +127,38 @@ namespace Orchard.Roles.Controllers {
try {
UpdateModel(viewModel);
// Save
if (!String.IsNullOrEmpty(HttpContext.Request.Form["submit.Save"])) {
List<string> rolePermissions = new List<string>();
foreach (string key in Request.Form.Keys) {
if (key.StartsWith("Checkbox.") && Request.Form[key] == "true") {
string permissionName = key.Substring("Checkbox.".Length);
rolePermissions.Add(permissionName);
}
List<string> rolePermissions = new List<string>();
foreach (string key in Request.Form.Keys) {
if (key.StartsWith("Checkbox.") && Request.Form[key] == "true") {
string permissionName = key.Substring("Checkbox.".Length);
rolePermissions.Add(permissionName);
}
_roleService.UpdateRole(viewModel.Id, viewModel.Name, rolePermissions);
}
else if (!String.IsNullOrEmpty(HttpContext.Request.Form["submit.Delete"])) {
_roleService.DeleteRole(viewModel.Id);
}
return RedirectToAction("Edit", new { viewModel.Id });
_roleService.UpdateRole(viewModel.Id, viewModel.Name, rolePermissions);
Services.Notifier.Information(T("Your Role has been saved."));
return RedirectToAction("Edit", new { id });
}
catch (Exception exception) {
Services.Notifier.Error(T("Editing Role failed: {0}", exception.Message));
return RedirectToAction("Edit", viewModel.Id);
return RedirectToAction("Edit", id);
}
}
[HttpPost, ActionName("Edit")]
[FormValueRequired("submit.Delete")]
public ActionResult EditDeletePOST(int id) {
if (!Services.Authorizer.Authorize(Permissions.ManageRoles, T("Not authorized to manage roles")))
return new HttpUnauthorizedResult();
try {
_roleService.DeleteRole(id);
Services.Notifier.Information(T("Role was successfully deleted."));
return RedirectToAction("Index");
} catch (Exception exception) {
Services.Notifier.Error(T("Editing Role failed: {0}", exception.Message));
return RedirectToAction("Edit", id);
}
}
}

View File

@@ -103,6 +103,10 @@
<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>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />

View File

@@ -9,24 +9,24 @@
<select id="Select1" name="roleActions">
<option value="1">@T("Remove")</option>
</select>
<input class="button" type="submit" value="@T("Apply")" />
</fieldset>
<input class="button" type="submit" value="@T("Apply")" />
</fieldset>
<div class="manage">@Html.ActionLink(T("Add a role").ToString(), "Create", new { }, new { @class = "button primaryAction" })</div>
<fieldset>
<table class="items" summary="@T("This is a table of the roles currently available for use in your application.")">
<colgroup>
<col id="Col1" />
<col id="Col2" />
<col id="Col3" />
</colgroup>
<thead>
<tr>
<th scope="col">&nbsp;&darr;</th>
<th scope="col">@T("Name")</th>
<th scope="col"></th>
</tr>
</thead>
@foreach (var row in Model.Rows) {
<col id="Col2" />
<col id="Col3" />
</colgroup>
<thead>
<tr>
<th scope="col">&nbsp;&darr;</th>
<th scope="col">@T("Name")</th>
<th scope="col"></th>
</tr>
</thead>
@foreach (var row in Model.Rows) {
<tr>
<td><input type="checkbox" value="true" name="@("Checkbox." + row.Id)"/></td>
<td>@row.Name</td>
@@ -34,7 +34,5 @@
</tr>
}
</table>
</fieldset>
}

View File

@@ -44,9 +44,10 @@ namespace Orchard.Widgets.Controllers {
layers.First() :
layers.FirstOrDefault(layer => layer.Id == id);
if (currentLayer == null) {
if (currentLayer == null &&
id != null) {
// Incorrect layer id passed
Services.Notifier.Error(T("Layer not found: {1}", id));
Services.Notifier.Error(T("Layer not found: {0}", id));
return RedirectToAction("Index");
}
@@ -254,7 +255,7 @@ namespace Orchard.Widgets.Controllers {
try {
widgetPart = _widgetsService.GetWidget(id);
if (widgetPart == null) {
Services.Notifier.Error(T("Widget not found: {1}", id));
Services.Notifier.Error(T("Widget not found: {0}", id));
return RedirectToAction("Index");
}

View File

@@ -243,9 +243,8 @@
<IISUrl>
</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
</CustomServerUrl>
<UseCustomServer>True</UseCustomServer>
<CustomServerUrl>http://orchard.codeplex.com</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>

View File

@@ -479,22 +479,14 @@ ul.comments li div.text {
/*border:1px solid #ff0000;*/
}
/* If zones 1 and 2 are empty in the quad */
/* If zone 1 is empty and 2, 3, 4 are not */
.split-234 #footer-quad-second div.zone { width:480px; }
.split-left #footer-quad-third div.zone {
width:600px;
}
/* If zone 2 is empty and 1, 3, 4 are not */
.split-134 #footer-quad-first div.zone { width:480px; }
.split-left #footer-quad-fourth div.zone {
width:360px;
}
/* If zone 3 is empty and 1, 2, 4 are not */
.split-124 #footer-quad-fourth div.zone { width:480px; }
/* If zones 3 and 4 are empty in the quad */
.split-right #footer-quad-first div.zone {
width:600px;
}
.split-right #footer-quad-second div.zone {
width:360px;
}
/* If zone 4 is empty and 1, 2, 3 are not */
.split-123 #footer-quad-third div.zone { width:480px; }

View File

@@ -21,13 +21,25 @@
else {
}
// Debug Quad
// {WorkContext.Layout.FooterQuadSecond.Add("2 This is some test text to see if zones are working. This is some test text to see if zones are working.");}
// {WorkContext.Layout.FooterQuadFirst.Add("1 This is some test text to see if zones are working. This is some test text to see if zones are working.");}
// {WorkContext.Layout.FooterQuadThird.Add("3 This is some test text to see if zones are working. This is some test text to see if zones are working.");}
//Add classes to the wrapper div to toggle quad widget zones on and off
if (Model.FooterQuadFirst == null && Model.FooterQuadSecond == null) {
Model.Classes.Add("split-left");
if (Model.FooterQuadFirst == null && Model.FooterQuadSecond != null && Model.FooterQuadThird != null && Model.FooterQuadFourth != null) {
Model.Classes.Add("split-234");
}
else if (Model.FooterQuadThird == null && Model.FooterQuadFourth == null) {
Model.Classes.Add("split-right");
else if (Model.FooterQuadFirst != null && Model.FooterQuadSecond == null && Model.FooterQuadThird != null && Model.FooterQuadFourth != null) {
Model.Classes.Add("split-134");
}
else if (Model.FooterQuadFirst != null && Model.FooterQuadSecond != null && Model.FooterQuadThird == null && Model.FooterQuadFourth != null) {
Model.Classes.Add("split-124");
}
else if (Model.FooterQuadFirst != null && Model.FooterQuadSecond != null && Model.FooterQuadThird != null && Model.FooterQuadFourth == null) {
Model.Classes.Add("split-123");
}
else {

View File

@@ -195,7 +195,6 @@ namespace Orchard.Mvc.Html {
return value.HasValue ? htmlHelper.DateTimeRelative(value.Value, T) : defaultIfNull;
}
//TODO: (erikpo) This method needs localized
public static LocalizedString DateTimeRelative(this HtmlHelper htmlHelper, DateTime value, Localizer T) {
var time = htmlHelper.Resolve<IClock>().UtcNow - value;