- @// todo: make these real (including markup)
-
-
-
-
-
- ", ResolveUrl("~/Media/" + Model.RelativePath + "/" + Model.Name), 500, 375)" />
- @T("Copy this html to add this image to your site.")
-
-
-
- *@
- }
+ }
+
\ No newline at end of file
From b77e52244bfc118c0d5e8a32778c962744a80171 Mon Sep 17 00:00:00 2001
From: Andre Rodrigues
Date: Wed, 24 Nov 2010 13:45:49 -0800
Subject: [PATCH 06/70] Moving permissions to initial validations. Removing
if/else for form post and using annotation instead.
--HG--
branch : dev
---
.../Controllers/AdminController.cs | 114 +++++++++++-------
1 file changed, 68 insertions(+), 46 deletions(-)
diff --git a/src/Orchard.Web/Modules/Orchard.Media/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.Media/Controllers/AdminController.cs
index f5b2fe736..45eeea110 100644
--- a/src/Orchard.Web/Modules/Orchard.Media/Controllers/AdminController.cs
+++ b/src/Orchard.Web/Modules/Orchard.Media/Controllers/AdminController.cs
@@ -3,15 +3,12 @@ using System.Collections.Generic;
using System.IO;
using System.Web;
using System.Web.Mvc;
-using JetBrains.Annotations;
-using Orchard.ContentManagement;
+using Orchard.Core.Contents.Controllers;
using Orchard.Localization;
using Orchard.Media.Models;
using Orchard.Media.Services;
using Orchard.Media.ViewModels;
-using Orchard.Settings;
using Orchard.UI.Notify;
-using Orchard.Utility.Extensions;
namespace Orchard.Media.Controllers {
[ValidateInput(false)]
@@ -56,11 +53,13 @@ namespace Orchard.Media.Controllers {
[HttpPost]
public ActionResult Create() {
+ if (!Services.Authorizer.Authorize(Permissions.ManageMediaFiles, T("Couldn't create media folder")))
+ return new HttpUnauthorizedResult();
+
var viewModel = new MediaFolderCreateViewModel();
try {
UpdateModel(viewModel);
- if (!Services.Authorizer.Authorize(Permissions.ManageMediaFiles, T("Couldn't create media folder")))
- return new HttpUnauthorizedResult();
+
_mediaService.CreateFolder(viewModel.MediaPath, viewModel.Name);
return RedirectToAction("Index");
}
@@ -109,24 +108,16 @@ namespace Orchard.Media.Controllers {
return View(model);
}
- [HttpPost]
- public ActionResult EditProperties() {
+ [HttpPost, ActionName("EditProperties")]
+ [FormValueRequired("submit.Delete")]
+ public ActionResult EditPropertiesDeletePOST() {
var viewModel = new MediaFolderEditPropertiesViewModel();
try {
UpdateModel(viewModel);
- //TODO: There may be better ways to do this.
- // Delete
- if (!String.IsNullOrEmpty(HttpContext.Request.Form["submit.Delete"])) {
- if (!Services.Authorizer.Authorize(Permissions.ManageMediaFiles, T("Couldn't delete media folder")))
- return new HttpUnauthorizedResult();
- _mediaService.DeleteFolder(viewModel.MediaPath);
- }
- // Save
- else {
- if (!Services.Authorizer.Authorize(Permissions.ManageMediaFiles, T("Couldn't rename media folder")))
- return new HttpUnauthorizedResult();
- _mediaService.RenameFolder(viewModel.MediaPath, viewModel.Name);
- }
+
+ if (!Services.Authorizer.Authorize(Permissions.ManageMediaFiles, T("Couldn't delete media folder")))
+ return new HttpUnauthorizedResult();
+ _mediaService.DeleteFolder(viewModel.MediaPath);
return RedirectToAction("Index");
}
@@ -136,6 +127,25 @@ namespace Orchard.Media.Controllers {
}
}
+ [HttpPost, ActionName("EditProperties")]
+ [FormValueRequired("submit.Save")]
+ public ActionResult EditProperties() {
+ if (!Services.Authorizer.Authorize(Permissions.ManageMediaFiles, T("Couldn't rename media folder")))
+ return new HttpUnauthorizedResult();
+
+ var viewModel = new MediaFolderEditPropertiesViewModel();
+ try {
+ UpdateModel(viewModel);
+
+ _mediaService.RenameFolder(viewModel.MediaPath, viewModel.Name);
+
+ return RedirectToAction("Index");
+ } catch (Exception exception) {
+ Services.Notifier.Error(T("Modifying Folder Properties failed: {0}", exception.Message));
+ return View(viewModel);
+ }
+ }
+
public ActionResult Add(string folderName, string mediaPath) {
var model = new MediaItemAddViewModel { FolderName = folderName, MediaPath = mediaPath };
return View(model);
@@ -143,11 +153,12 @@ namespace Orchard.Media.Controllers {
[HttpPost]
public ActionResult Add() {
+ if (!Services.Authorizer.Authorize(Permissions.UploadMediaFiles, T("Couldn't upload media file")))
+ return new HttpUnauthorizedResult();
+
var viewModel = new MediaItemAddViewModel();
try {
UpdateModel(viewModel);
- if (!Services.Authorizer.Authorize(Permissions.UploadMediaFiles, T("Couldn't upload media file")))
- return new HttpUnauthorizedResult();
if(String.IsNullOrWhiteSpace(Request.Files[0].FileName)) {
ModelState.AddModelError("File", T("Select a file to upload").ToString());
@@ -180,11 +191,12 @@ namespace Orchard.Media.Controllers {
[HttpPost]
public ContentResult AddFromClient() {
+ if (!Services.Authorizer.Authorize(Permissions.UploadMediaFiles))
+ return Content(string.Format("", T("ERROR: You don't have permission to upload media files")));
+
var viewModel = new MediaItemAddViewModel();
try {
UpdateModel(viewModel);
- if (!Services.Authorizer.Authorize(Permissions.UploadMediaFiles))
- return Content(string.Format("", T("ERROR: You don't have permission to upload media files")));
if (Request.Files.Count < 1 || Request.Files[0].ContentLength == 0)
return Content(string.Format("", T("HEY: You didn't give me a file to upload")));
@@ -220,32 +232,42 @@ namespace Orchard.Media.Controllers {
return View(model);
}
- [HttpPost]
- public ActionResult EditMedia(FormCollection input) {
+ [HttpPost, ActionName("EditMedia")]
+ [FormValueRequired("submit.Delete")]
+ public ActionResult EditMediaDeletePOST(FormCollection input) {
+ if (!Services.Authorizer.Authorize(Permissions.ManageMediaFiles, T("Couldn't delete media file")))
+ return new HttpUnauthorizedResult();
+
var viewModel = new MediaItemEditViewModel();
try {
UpdateModel(viewModel);
- if (!Services.Authorizer.Authorize(Permissions.ManageMediaFiles, T("Couldn't modify media file")))
- return new HttpUnauthorizedResult();
- // Delete
- if (!String.IsNullOrEmpty(HttpContext.Request.Form["submit.Delete"])) {
- if (!Services.Authorizer.Authorize(Permissions.ManageMediaFiles, T("Couldn't delete media file")))
- return new HttpUnauthorizedResult();
- _mediaService.DeleteFile(viewModel.Name, viewModel.MediaPath);
- return RedirectToAction("Edit", new { name = viewModel.FolderName, mediaPath = viewModel.MediaPath });
- }
- // Save and Rename
+
+ _mediaService.DeleteFile(viewModel.Name, viewModel.MediaPath);
+ return RedirectToAction("Edit", new { name = viewModel.FolderName, mediaPath = viewModel.MediaPath });
+ } catch (Exception exception) {
+ Services.Notifier.Error(T("Removing media file failed: {0}", exception.Message));
+ return View(viewModel);
+ }
+ }
+
+ [HttpPost, ActionName("EditMedia")]
+ [FormValueRequired("submit.Save")]
+ public ActionResult EditMedia(FormCollection input) {
+ if (!Services.Authorizer.Authorize(Permissions.ManageMediaFiles, T("Couldn't modify media file")))
+ return new HttpUnauthorizedResult();
+
+ var viewModel = new MediaItemEditViewModel();
+ try {
+ UpdateModel(viewModel);
+ string viewModelName = viewModel.Name;
+
+ // Rename
if (!String.Equals(viewModel.Name, input["NewName"], StringComparison.OrdinalIgnoreCase)) {
_mediaService.RenameFile(viewModel.Name, input["NewName"], viewModel.MediaPath);
- return RedirectToAction("EditMedia", new { name = input["NewName"],
- caption = viewModel.Caption,
- lastUpdated = viewModel.LastUpdated,
- size = viewModel.Size,
- folderName = viewModel.FolderName,
- mediaPath = viewModel.MediaPath });
+ viewModelName = input["NewName"];
}
- // Save
- return RedirectToAction("EditMedia", new { name = viewModel.Name,
+
+ return RedirectToAction("EditMedia", new { name = viewModelName,
caption = viewModel.Caption,
lastUpdated = viewModel.LastUpdated,
size = viewModel.Size,
@@ -258,4 +280,4 @@ namespace Orchard.Media.Controllers {
}
}
}
-}
+}
\ No newline at end of file
From 26524253782d271f8d6e597f3b1f10e598511e26 Mon Sep 17 00:00:00 2001
From: Andre Rodrigues
Date: Wed, 24 Nov 2010 14:10:33 -0800
Subject: [PATCH 07/70] #16864 Making invalid rename to fail.
--HG--
branch : dev
---
.../Modules/Orchard.Media/Controllers/AdminController.cs | 5 +++--
.../Modules/Orchard.Media/Services/MediaService.cs | 6 ++++--
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/src/Orchard.Web/Modules/Orchard.Media/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.Media/Controllers/AdminController.cs
index 45eeea110..ba6b08c0d 100644
--- a/src/Orchard.Web/Modules/Orchard.Media/Controllers/AdminController.cs
+++ b/src/Orchard.Web/Modules/Orchard.Media/Controllers/AdminController.cs
@@ -111,12 +111,13 @@ namespace Orchard.Media.Controllers {
[HttpPost, ActionName("EditProperties")]
[FormValueRequired("submit.Delete")]
public ActionResult EditPropertiesDeletePOST() {
+ if (!Services.Authorizer.Authorize(Permissions.ManageMediaFiles, T("Couldn't delete media folder")))
+ return new HttpUnauthorizedResult();
+
var viewModel = new MediaFolderEditPropertiesViewModel();
try {
UpdateModel(viewModel);
- if (!Services.Authorizer.Authorize(Permissions.ManageMediaFiles, T("Couldn't delete media folder")))
- return new HttpUnauthorizedResult();
_mediaService.DeleteFolder(viewModel.MediaPath);
return RedirectToAction("Index");
diff --git a/src/Orchard.Web/Modules/Orchard.Media/Services/MediaService.cs b/src/Orchard.Web/Modules/Orchard.Media/Services/MediaService.cs
index e990545bb..459264f0e 100644
--- a/src/Orchard.Web/Modules/Orchard.Media/Services/MediaService.cs
+++ b/src/Orchard.Web/Modules/Orchard.Media/Services/MediaService.cs
@@ -83,9 +83,11 @@ namespace Orchard.Media.Services {
}
public void RenameFile(string name, string newName, string folderName) {
- if (FileAllowed(newName, false)) {
- _storageProvider.RenameFile(_storageProvider.Combine(folderName, name), _storageProvider.Combine(folderName, newName));
+ if (!FileAllowed(newName, false)) {
+ throw new ArgumentException("New file name " + newName + " not allowed.");
}
+
+ _storageProvider.RenameFile(_storageProvider.Combine(folderName, name), _storageProvider.Combine(folderName, newName));
}
public string UploadMediaFile(string folderName, HttpPostedFileBase postedFile) {
From 81018a76d254fd475ef4d84ddadac80461b57527 Mon Sep 17 00:00:00 2001
From: Renaud Paquay
Date: Wed, 24 Nov 2010 14:28:15 -0800
Subject: [PATCH 08/70] Orchard.exe commands should be case-insensitive
Make commands and switch case insensitive. Also change the property value
code to use "System.Convert" instead of hand-coded convertion code.
Work Items: 16590
--HG--
branch : dev
---
.../Commands/DefaultOrchardCommandHandler.cs | 69 +++++++++----------
.../Commands/OrchardSwitchesAttribute.cs | 18 +++--
2 files changed, 41 insertions(+), 46 deletions(-)
diff --git a/src/Orchard/Commands/DefaultOrchardCommandHandler.cs b/src/Orchard/Commands/DefaultOrchardCommandHandler.cs
index bd323ea95..df74cfa06 100644
--- a/src/Orchard/Commands/DefaultOrchardCommandHandler.cs
+++ b/src/Orchard/Commands/DefaultOrchardCommandHandler.cs
@@ -13,54 +13,50 @@ namespace Orchard.Commands {
public Localizer T { get; set; }
public CommandContext Context { get; set; }
- #region Implementation of ICommandHandler
-
public void Execute(CommandContext context) {
SetSwitchValues(context);
Invoke(context);
}
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "System.Int32.TryParse(System.String,System.Int32@)")]
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "System.Boolean.TryParse(System.String,System.Boolean@)")]
private void SetSwitchValues(CommandContext context) {
if (context.Switches != null && context.Switches.Any()) {
foreach (var commandSwitch in context.Switches) {
- PropertyInfo propertyInfo = GetType().GetProperty(commandSwitch.Key);
- if (propertyInfo == null) {
- throw new InvalidOperationException(T("Switch \"{0}\" was not found", commandSwitch.Key).Text);
- }
- if (propertyInfo.GetCustomAttributes(typeof(OrchardSwitchAttribute), false).Length == 0) {
- throw new InvalidOperationException(T("A property \"{0}\" exists but is not decorated with \"{1}\"", commandSwitch.Key, typeof(OrchardSwitchAttribute).Name).Text);
- }
- if (propertyInfo.PropertyType.IsAssignableFrom(typeof(bool))) {
- bool boolValue;
- // todo: might be better to throw here if TryParse returns false instead of silently using 'false', to catch types (e.g. 'ture')
- Boolean.TryParse(commandSwitch.Value, out boolValue);
- propertyInfo.SetValue(this, boolValue, null);
- }
- else if (propertyInfo.PropertyType.IsAssignableFrom(typeof(int))) {
- int intValue;
- // todo: might be better to throw here if TryParse returns false instead of silently using 0 value
- Int32.TryParse(commandSwitch.Value, out intValue);
- propertyInfo.SetValue(this, intValue, null);
- }
- else if (propertyInfo.PropertyType.IsAssignableFrom(typeof(string))) {
- propertyInfo.SetValue(this, commandSwitch.Value, null);
- }
- else {
- throw new InvalidOperationException(T("No property named \"{0}\" found of type bool, int or string.", commandSwitch).Text);
- }
+ SetSwitchValue(commandSwitch);
}
}
}
+ private void SetSwitchValue(KeyValuePair commandSwitch) {
+ // Find the property
+ PropertyInfo propertyInfo = GetType().GetProperty(commandSwitch.Key, BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase);
+ if (propertyInfo == null) {
+ throw new ArgumentException(T("Switch \"{0}\" was not found", commandSwitch.Key).Text);
+ }
+ if (propertyInfo.GetCustomAttributes(typeof(OrchardSwitchAttribute), false).Length == 0) {
+ throw new ArgumentException(T("A property \"{0}\" exists but is not decorated with \"{1}\"", commandSwitch.Key, typeof(OrchardSwitchAttribute).Name).Text);
+ }
+
+ // Set the value
+ try {
+ object value = Convert.ChangeType(commandSwitch.Value, propertyInfo.PropertyType);
+ propertyInfo.SetValue(this, value, null/*index*/);
+ }
+ catch(Exception e) {
+ string message = T("Error converting value \"{0}\" to \"{1}\" for switch \"{2}\"",
+ LocalizedString.TextOrDefault(commandSwitch.Value, T("(empty)")),
+ propertyInfo.PropertyType.FullName,
+ commandSwitch.Key).Text;
+ throw new ArgumentException(message, e);
+ }
+ }
+
private void Invoke(CommandContext context) {
CheckMethodForSwitches(context.CommandDescriptor.MethodInfo, context.Switches);
var arguments = (context.Arguments ?? Enumerable.Empty()).ToArray();
object[] invokeParameters = GetInvokeParametersForMethod(context.CommandDescriptor.MethodInfo, arguments);
if (invokeParameters == null) {
- throw new InvalidOperationException(T("Command arguments \"{0}\" don't match command definition", string.Join(" ", arguments)).ToString());
+ throw new ArgumentException(T("Command arguments \"{0}\" don't match command definition", string.Join(" ", arguments)).ToString());
}
this.Context = context;
@@ -76,7 +72,8 @@ namespace Orchard.Commands {
bool methodHasParams = false;
if (methodParameters.Length == 0) {
- if (args.Count == 0) return invokeParameters.ToArray();
+ if (args.Count == 0)
+ return invokeParameters.ToArray();
return null;
}
@@ -103,17 +100,17 @@ namespace Orchard.Commands {
private void CheckMethodForSwitches(MethodInfo methodInfo, IDictionary switches) {
if (switches == null || switches.Count == 0)
return;
- var supportedSwitches = new List();
+
+ var supportedSwitches = new HashSet(StringComparer.OrdinalIgnoreCase);
foreach (OrchardSwitchesAttribute switchesAttribute in methodInfo.GetCustomAttributes(typeof(OrchardSwitchesAttribute), false)) {
- supportedSwitches.AddRange(switchesAttribute.SwitchName);
+ supportedSwitches.UnionWith(switchesAttribute.Switches);
}
+
foreach (var commandSwitch in switches.Keys) {
if (!supportedSwitches.Contains(commandSwitch)) {
- throw new InvalidOperationException(T("Method \"{0}\" does not support switch \"{1}\".", methodInfo.Name, commandSwitch).ToString());
+ throw new ArgumentException(T("Method \"{0}\" does not support switch \"{1}\".", methodInfo.Name, commandSwitch).ToString());
}
}
}
-
- #endregion
}
}
diff --git a/src/Orchard/Commands/OrchardSwitchesAttribute.cs b/src/Orchard/Commands/OrchardSwitchesAttribute.cs
index b83bb06f5..9c0eda27a 100644
--- a/src/Orchard/Commands/OrchardSwitchesAttribute.cs
+++ b/src/Orchard/Commands/OrchardSwitchesAttribute.cs
@@ -1,22 +1,20 @@
using System;
using System.Collections.Generic;
+using System.Linq;
namespace Orchard.Commands {
[AttributeUsage(AttributeTargets.Method)]
public class OrchardSwitchesAttribute : Attribute {
- private readonly IEnumerable _switches;
+ private readonly string _switches;
public OrchardSwitchesAttribute(string switches) {
- List switchList = new List();
- foreach (var s in switches.Split(',')) {
- switchList.Add(s.Trim());
+ _switches = switches;
+ }
+
+ public IEnumerable Switches {
+ get {
+ return (_switches ?? "").Trim().Split(',').Select(s => s.Trim());
}
- _switches = switchList;
}
-
- public IEnumerable SwitchName {
- get { return _switches; }
- }
-
}
}
From fd4c58d4b40081a2314491a485c0b696bc32211e Mon Sep 17 00:00:00 2001
From: Andre Rodrigues
Date: Wed, 24 Nov 2010 15:19:14 -0800
Subject: [PATCH 09/70] Initializing localizer Adding information notifications
Adding localization invocations where necessary Replacing tabs for spaces in
views
--HG--
branch : dev
---
.../Modules/Orchard.Media/AdminMenu.cs | 6 ++++-
.../Controllers/AdminController.cs | 18 +++++++++++--
.../Orchard.Media/Helpers/MediaHelpers.cs | 2 +-
.../Orchard.Media/Models/MediaSettingsPart.cs | 1 -
.../Models/MediaSettingsPartRecord.cs | 3 +--
.../Orchard.Media/Services/MediaService.cs | 9 ++++---
.../Orchard.Media/Views/Admin/Add.cshtml | 6 ++---
.../Orchard.Media/Views/Admin/Create.cshtml | 16 +++++------
.../Views/Admin/EditMedia.cshtml | 2 +-
.../Views/Admin/EditProperties.cshtml | 7 +++--
.../Media/FileSystemStorageProvider.cs | 27 +++++++++++--------
11 files changed, 59 insertions(+), 38 deletions(-)
diff --git a/src/Orchard.Web/Modules/Orchard.Media/AdminMenu.cs b/src/Orchard.Web/Modules/Orchard.Media/AdminMenu.cs
index 3b8f4f804..38a9ac151 100644
--- a/src/Orchard.Web/Modules/Orchard.Media/AdminMenu.cs
+++ b/src/Orchard.Web/Modules/Orchard.Media/AdminMenu.cs
@@ -5,6 +5,10 @@ namespace Orchard.Media {
public class AdminMenu : INavigationProvider {
public Localizer T { get; set; }
+ public AdminMenu() {
+ T = NullLocalizer.Instance;
+ }
+
public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) {
@@ -13,4 +17,4 @@ namespace Orchard.Media {
.Permission(Permissions.ManageMediaFiles)));
}
}
-}
+}
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.Media/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.Media/Controllers/AdminController.cs
index ba6b08c0d..a8c7552b2 100644
--- a/src/Orchard.Web/Modules/Orchard.Media/Controllers/AdminController.cs
+++ b/src/Orchard.Web/Modules/Orchard.Media/Controllers/AdminController.cs
@@ -18,6 +18,8 @@ namespace Orchard.Media.Controllers {
public AdminController(IOrchardServices services, IMediaService mediaService) {
Services = services;
_mediaService = mediaService;
+
+ T = NullLocalizer.Instance;
}
public IOrchardServices Services { get; set;}
@@ -61,6 +63,8 @@ namespace Orchard.Media.Controllers {
UpdateModel(viewModel);
_mediaService.CreateFolder(viewModel.MediaPath, viewModel.Name);
+
+ Services.Notifier.Information(T("Media folder created"));
return RedirectToAction("Index");
}
catch (Exception exception) {
@@ -86,6 +90,8 @@ namespace Orchard.Media.Controllers {
if (!Services.Authorizer.Authorize(Permissions.ManageMediaFiles, T("Couldn't delete media file")))
return new HttpUnauthorizedResult();
_mediaService.DeleteFile(fileName, folderName);
+
+ Services.Notifier.Information(T("Media file deleted"));
}
else if (key.StartsWith("Checkbox.Folder.") && input[key] == "true") {
string folderName = key.Substring("Checkbox.Folder.".Length);
@@ -93,6 +99,8 @@ namespace Orchard.Media.Controllers {
if (!Services.Authorizer.Authorize(Permissions.ManageMediaFiles, T("Couldn't delete media folder")))
return new HttpUnauthorizedResult();
_mediaService.DeleteFolder(folderPath);
+
+ Services.Notifier.Information(T("Media folder deleted"));
}
}
return RedirectToAction("Index");
@@ -120,10 +128,11 @@ namespace Orchard.Media.Controllers {
_mediaService.DeleteFolder(viewModel.MediaPath);
+ Services.Notifier.Information(T("Media folder deleted"));
return RedirectToAction("Index");
}
catch (Exception exception) {
- Services.Notifier.Error(T("Modifying Folder Properties failed: {0}", exception.Message));
+ Services.Notifier.Error(T("Deleting media folder failed: {0}", exception.Message));
return View(viewModel);
}
}
@@ -140,9 +149,10 @@ namespace Orchard.Media.Controllers {
_mediaService.RenameFolder(viewModel.MediaPath, viewModel.Name);
+ Services.Notifier.Information(T("Media folder properties modified"));
return RedirectToAction("Index");
} catch (Exception exception) {
- Services.Notifier.Error(T("Modifying Folder Properties failed: {0}", exception.Message));
+ Services.Notifier.Error(T("Modifying media folder properties failed: {0}", exception.Message));
return View(viewModel);
}
}
@@ -182,6 +192,7 @@ namespace Orchard.Media.Controllers {
_mediaService.UploadMediaFile(viewModel.MediaPath, file);
}
+ Services.Notifier.Information(T("Media file(s) uploaded"));
return RedirectToAction("Edit", new { name = viewModel.FolderName, mediaPath = viewModel.MediaPath });
}
catch (Exception exception) {
@@ -244,6 +255,8 @@ namespace Orchard.Media.Controllers {
UpdateModel(viewModel);
_mediaService.DeleteFile(viewModel.Name, viewModel.MediaPath);
+
+ Services.Notifier.Information(T("Media deleted"));
return RedirectToAction("Edit", new { name = viewModel.FolderName, mediaPath = viewModel.MediaPath });
} catch (Exception exception) {
Services.Notifier.Error(T("Removing media file failed: {0}", exception.Message));
@@ -268,6 +281,7 @@ namespace Orchard.Media.Controllers {
viewModelName = input["NewName"];
}
+ Services.Notifier.Information(T("Media information updated"));
return RedirectToAction("EditMedia", new { name = viewModelName,
caption = viewModel.Caption,
lastUpdated = viewModel.LastUpdated,
diff --git a/src/Orchard.Web/Modules/Orchard.Media/Helpers/MediaHelpers.cs b/src/Orchard.Web/Modules/Orchard.Media/Helpers/MediaHelpers.cs
index f9cadb0b7..d66cfab42 100644
--- a/src/Orchard.Web/Modules/Orchard.Media/Helpers/MediaHelpers.cs
+++ b/src/Orchard.Web/Modules/Orchard.Media/Helpers/MediaHelpers.cs
@@ -25,4 +25,4 @@ namespace Orchard.Media.Helpers {
return navigations;
}
}
-}
+}
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.Media/Models/MediaSettingsPart.cs b/src/Orchard.Web/Modules/Orchard.Media/Models/MediaSettingsPart.cs
index 39228bf9c..f4123e9b6 100644
--- a/src/Orchard.Web/Modules/Orchard.Media/Models/MediaSettingsPart.cs
+++ b/src/Orchard.Web/Modules/Orchard.Media/Models/MediaSettingsPart.cs
@@ -1,5 +1,4 @@
using Orchard.ContentManagement;
-using System;
namespace Orchard.Media.Models {
public class MediaSettingsPart : ContentPart {
diff --git a/src/Orchard.Web/Modules/Orchard.Media/Models/MediaSettingsPartRecord.cs b/src/Orchard.Web/Modules/Orchard.Media/Models/MediaSettingsPartRecord.cs
index 758732576..8260d9c47 100644
--- a/src/Orchard.Web/Modules/Orchard.Media/Models/MediaSettingsPartRecord.cs
+++ b/src/Orchard.Web/Modules/Orchard.Media/Models/MediaSettingsPartRecord.cs
@@ -1,6 +1,5 @@
-using System.Net.Mail;
-using Orchard.ContentManagement.Records;
using System.ComponentModel.DataAnnotations;
+using Orchard.ContentManagement.Records;
namespace Orchard.Media.Models {
public class MediaSettingsPartRecord : ContentPartRecord {
diff --git a/src/Orchard.Web/Modules/Orchard.Media/Services/MediaService.cs b/src/Orchard.Web/Modules/Orchard.Media/Services/MediaService.cs
index 459264f0e..2a5087227 100644
--- a/src/Orchard.Web/Modules/Orchard.Media/Services/MediaService.cs
+++ b/src/Orchard.Web/Modules/Orchard.Media/Services/MediaService.cs
@@ -6,7 +6,7 @@ using ICSharpCode.SharpZipLib.Zip;
using JetBrains.Annotations;
using Orchard.ContentManagement;
using Orchard.FileSystems.Media;
-using Orchard.Logging;
+using Orchard.Localization;
using Orchard.Media.Models;
namespace Orchard.Media.Services {
@@ -18,10 +18,11 @@ namespace Orchard.Media.Services {
public MediaService(IStorageProvider storageProvider, IOrchardServices orchardServices) {
_storageProvider = storageProvider;
_orchardServices = orchardServices;
- Logger = NullLogger.Instance;
+
+ T = NullLocalizer.Instance;
}
- public ILogger Logger { get; set; }
+ public Localizer T { get; set; }
public string GetPublicUrl(string path) {
return _storageProvider.GetPublicUrl(path);
@@ -84,7 +85,7 @@ namespace Orchard.Media.Services {
public void RenameFile(string name, string newName, string folderName) {
if (!FileAllowed(newName, false)) {
- throw new ArgumentException("New file name " + newName + " not allowed.");
+ throw new ArgumentException(T("New file name {0} not allowed", newName).ToString());
}
_storageProvider.RenameFile(_storageProvider.Combine(folderName, name), _storageProvider.Combine(folderName, newName));
diff --git a/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Add.cshtml b/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Add.cshtml
index 81ecc38c4..fa2482645 100644
--- a/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Add.cshtml
+++ b/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Add.cshtml
@@ -17,12 +17,12 @@
- @T("After your files have been uploaded, you can edit the titles and descriptions.")
+ @T("After your files have been uploaded, you can edit the titles and descriptions.")
- @Html.AntiForgeryTokenOrchard()
-
+ @Html.AntiForgeryTokenOrchard()
+
}
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Create.cshtml b/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Create.cshtml
index 3267dbdec..e743a0723 100644
--- a/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Create.cshtml
+++ b/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Create.cshtml
@@ -6,20 +6,20 @@
@Html.TitleForPage(T("Add a Folder").ToString())
@Html.ActionLink(T("Media Folders").ToString(), "Index") >
- @foreach (FolderNavigation navigation in MediaHelpers.GetFolderNavigationHierarchy(Model.MediaPath)) {
- @Html.ActionLink(navigation.FolderName, "Edit", new {name = navigation.FolderName, mediaPath = navigation.FolderPath}) >
- }
- @T("Add a Folder")
+ @foreach (FolderNavigation navigation in MediaHelpers.GetFolderNavigationHierarchy(Model.MediaPath)) {
+ @Html.ActionLink(navigation.FolderName, "Edit", new {name = navigation.FolderName, mediaPath = navigation.FolderPath}) >
+ }
+ @T("Add a Folder")
}
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/EditMedia.cshtml b/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/EditMedia.cshtml
index c99882e08..4cb9c1686 100644
--- a/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/EditMedia.cshtml
+++ b/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/EditMedia.cshtml
@@ -24,7 +24,7 @@
@* todo: make these real (including markup) *@
diff --git a/src/Orchard/FileSystems/Media/FileSystemStorageProvider.cs b/src/Orchard/FileSystems/Media/FileSystemStorageProvider.cs
index 5d7a16f48..26472144b 100644
--- a/src/Orchard/FileSystems/Media/FileSystemStorageProvider.cs
+++ b/src/Orchard/FileSystems/Media/FileSystemStorageProvider.cs
@@ -5,6 +5,7 @@ using System.IO;
using System.Linq;
using System.Web.Hosting;
using Orchard.Environment.Configuration;
+using Orchard.Localization;
namespace Orchard.FileSystems.Media {
public class FileSystemStorageProvider : IStorageProvider {
@@ -28,8 +29,12 @@ namespace Orchard.FileSystems.Media {
appPath = '/' + appPath;
_publicPath = appPath + "Media/" + settings.Name + "/";
+
+ T = NullLocalizer.Instance;
}
+ public Localizer T { get; set; }
+
string Map(string path) {
return string.IsNullOrEmpty(path) ? _storagePath : Path.Combine(_storagePath, path);
}
@@ -51,14 +56,14 @@ namespace Orchard.FileSystems.Media {
public IStorageFile GetFile(string path) {
if (!File.Exists(Map(path))) {
- throw new ArgumentException("File " + path + " does not exist");
+ throw new ArgumentException(T("File {0} does not exist", path).ToString());
}
return new FileSystemStorageFile(Fix(path), new FileInfo(Map(path)));
}
public IEnumerable ListFiles(string path) {
if (!Directory.Exists(Map(path))) {
- throw new ArgumentException("Directory " + path + " does not exist");
+ throw new ArgumentException(T("Directory {0} does not exist", path).ToString());
}
return new DirectoryInfo(Map(path))
@@ -74,7 +79,7 @@ namespace Orchard.FileSystems.Media {
Directory.CreateDirectory(Map(path));
}
catch (Exception ex) {
- throw new ArgumentException(string.Format("The folder could not be created at path: {0}. {1}", path, ex));
+ throw new ArgumentException(T("The folder could not be created at path: {0}. {1}", path, ex).ToString());
}
}
@@ -91,7 +96,7 @@ namespace Orchard.FileSystems.Media {
public void CreateFolder(string path) {
if (Directory.Exists(Map(path))) {
- throw new ArgumentException("Directory " + path + " already exists");
+ throw new ArgumentException(T("Directory {0} already exists", path).ToString());
}
Directory.CreateDirectory(Map(path));
@@ -99,7 +104,7 @@ namespace Orchard.FileSystems.Media {
public void DeleteFolder(string path) {
if (!Directory.Exists(Map(path))) {
- throw new ArgumentException("Directory " + path + " does not exist");
+ throw new ArgumentException(T("Directory {0} does not exist", path).ToString());
}
Directory.Delete(Map(path), true);
@@ -107,11 +112,11 @@ namespace Orchard.FileSystems.Media {
public void RenameFolder(string path, string newPath) {
if (!Directory.Exists(Map(path))) {
- throw new ArgumentException("Directory " + path + "does not exist");
+ throw new ArgumentException(T("Directory {0} does not exist", path).ToString());
}
if (Directory.Exists(Map(newPath))) {
- throw new ArgumentException("Directory " + newPath + " already exists");
+ throw new ArgumentException(T("Directory {0} already exists", newPath).ToString());
}
Directory.Move(Map(path), Map(newPath));
@@ -119,7 +124,7 @@ namespace Orchard.FileSystems.Media {
public IStorageFile CreateFile(string path) {
if (File.Exists(Map(path))) {
- throw new ArgumentException("File " + path + " already exists");
+ throw new ArgumentException(T("File {0} already exists", path).ToString());
}
var fileInfo = new FileInfo(Map(path));
@@ -130,7 +135,7 @@ namespace Orchard.FileSystems.Media {
public void DeleteFile(string path) {
if (!File.Exists(Map(path))) {
- throw new ArgumentException("File " + path + " does not exist");
+ throw new ArgumentException(T("File {0} does not exist", path).ToString());
}
File.Delete(Map(path));
@@ -138,11 +143,11 @@ namespace Orchard.FileSystems.Media {
public void RenameFile(string path, string newPath) {
if (!File.Exists(Map(path))) {
- throw new ArgumentException("File " + path + " does not exist");
+ throw new ArgumentException(T("File {0} does not exist", path).ToString());
}
if (File.Exists(Map(newPath))) {
- throw new ArgumentException("File " + newPath + " already exists");
+ throw new ArgumentException(T("File {0} already exists", newPath).ToString());
}
File.Move(Map(path), Map(newPath));
From 67a45f1c09993dc959571687c862e9394f177b1c Mon Sep 17 00:00:00 2001
From: Sebastien Ros
Date: Wed, 24 Nov 2010 15:24:11 -0800
Subject: [PATCH 10/70] Validating content type names, and displaying technical
names
Work Item: 16471
--HG--
branch : dev
---
src/Orchard.Specs/ContentTypes.feature | 84 ++++++
src/Orchard.Specs/ContentTypes.feature.cs | 276 ++++++++++++++++++
src/Orchard.Specs/Orchard.Specs.csproj | 9 +
.../Controllers/AdminController.cs | 23 +-
.../Services/ContentDefinitionService.cs | 33 ++-
.../Services/IContentDefinitionService.cs | 4 +-
.../ViewModels/CreateTypeViewModel.cs | 1 +
.../Views/Admin/Create.cshtml | 32 +-
.../Views/Admin/Edit.cshtml | 2 +-
9 files changed, 446 insertions(+), 18 deletions(-)
create mode 100644 src/Orchard.Specs/ContentTypes.feature
create mode 100644 src/Orchard.Specs/ContentTypes.feature.cs
diff --git a/src/Orchard.Specs/ContentTypes.feature b/src/Orchard.Specs/ContentTypes.feature
new file mode 100644
index 000000000..cb994d201
--- /dev/null
+++ b/src/Orchard.Specs/ContentTypes.feature
@@ -0,0 +1,84 @@
+Feature: Content Types
+ In order to add new types to my site
+ As an adminitrator
+ I want to create create content types
+
+Scenario: I can create a new content type
+ Given I have installed Orchard
+ And I have installed "Orchard.ContentTypes"
+ When I go to "Admin/ContentTypes"
+ Then I should see "]*>.*?Create new type"
+ When I go to "Admin/ContentTypes/Create"
+ And I fill in
+ | name | value |
+ | DisplayName | Event |
+ | Name | Event |
+ And I hit "Create"
+ And I go to "Admin/ContentTypes/"
+ Then I should see "Event"
+
+Scenario: I can't create a content type with an already existing name
+ Given I have installed Orchard
+ And I have installed "Orchard.ContentTypes"
+ When I go to "Admin/ContentTypes/Create"
+ And I fill in
+ | name | value |
+ | DisplayName | Event |
+ | Name | Event |
+ And I hit "Create"
+ And I go to "Admin/ContentTypes/"
+ Then I should see "Event"
+ When I go to "Admin/ContentTypes/Create"
+ And I fill in
+ | name | value |
+ | DisplayName | Event |
+ | Name | Event-2 |
+ And I hit "Create"
+ Then I should see "
]*>.*?New Content Type.*?
"
+ And I should see "validation-summary-errors"
+
+Scenario: I can't create a content type with an already existing technical name
+ Given I have installed Orchard
+ And I have installed "Orchard.ContentTypes"
+ When I go to "Admin/ContentTypes/Create"
+ And I fill in
+ | name | value |
+ | DisplayName | Dinner |
+ | Name | Dinner |
+ And I hit "Create"
+ And I go to "Admin/ContentTypes/"
+ Then I should see "Dinner"
+ When I go to "Admin/ContentTypes/Create"
+ And I fill in
+ | name | value |
+ | DisplayName | Dinner2 |
+ | Name | Dinner |
+ And I hit "Create"
+ Then I should see "
]*>.*?New Content Type.*?
"
+ And I should see "validation-summary-errors"
+
+Scenario: I can't rename a content type with an already existing name
+ Given I have installed Orchard
+ And I have installed "Orchard.ContentTypes"
+ When I go to "Admin/ContentTypes/Create"
+ And I fill in
+ | name | value |
+ | DisplayName | Dinner |
+ | Name | Dinner |
+ And I hit "Create"
+ And I go to "Admin/ContentTypes/"
+ Then I should see "Dinner"
+ When I go to "Admin/ContentTypes/Create"
+ And I fill in
+ | name | value |
+ | DisplayName | Event |
+ | Name | Event |
+ And I hit "Create"
+ And I go to "Admin/ContentTypes/"
+ Then I should see "Event"
+ When I go to "Admin/ContentTypes/Edit/Dinner"
+ And I fill in
+ | name | value |
+ | DisplayName | Event |
+ And I hit "Save"
+ Then I should see "validation-summary-errors"
diff --git a/src/Orchard.Specs/ContentTypes.feature.cs b/src/Orchard.Specs/ContentTypes.feature.cs
new file mode 100644
index 000000000..1d5dc2ee1
--- /dev/null
+++ b/src/Orchard.Specs/ContentTypes.feature.cs
@@ -0,0 +1,276 @@
+// ------------------------------------------------------------------------------
+//
+// This code was generated by SpecFlow (http://www.specflow.org/).
+// SpecFlow Version:1.3.0.0
+// Runtime Version:4.0.30319.1
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+// ------------------------------------------------------------------------------
+#region Designer generated code
+namespace Orchard.Specs
+{
+ using TechTalk.SpecFlow;
+
+
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.3.0.0")]
+ [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [NUnit.Framework.TestFixtureAttribute()]
+ [NUnit.Framework.DescriptionAttribute("Content Types")]
+ public partial class ContentTypesFeature
+ {
+
+ private static TechTalk.SpecFlow.ITestRunner testRunner;
+
+#line 1 "ContentTypes.feature"
+#line hidden
+
+ [NUnit.Framework.TestFixtureSetUpAttribute()]
+ public virtual void FeatureSetup()
+ {
+ testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner();
+ TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Content Types", "In order to add new types to my site\r\nAs an adminitrator\r\nI want to create create" +
+ " content types", ((string[])(null)));
+ testRunner.OnFeatureStart(featureInfo);
+ }
+
+ [NUnit.Framework.TestFixtureTearDownAttribute()]
+ public virtual void FeatureTearDown()
+ {
+ testRunner.OnFeatureEnd();
+ testRunner = null;
+ }
+
+ public virtual void ScenarioSetup(TechTalk.SpecFlow.ScenarioInfo scenarioInfo)
+ {
+ testRunner.OnScenarioStart(scenarioInfo);
+ }
+
+ [NUnit.Framework.TearDownAttribute()]
+ public virtual void ScenarioTearDown()
+ {
+ testRunner.OnScenarioEnd();
+ }
+
+ [NUnit.Framework.TestAttribute()]
+ [NUnit.Framework.DescriptionAttribute("I can create a new content type")]
+ public virtual void ICanCreateANewContentType()
+ {
+ TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can create a new content type", ((string[])(null)));
+#line 6
+this.ScenarioSetup(scenarioInfo);
+#line 7
+testRunner.Given("I have installed Orchard");
+#line 8
+testRunner.And("I have installed \"Orchard.ContentTypes\"");
+#line 9
+testRunner.When("I go to \"Admin/ContentTypes\"");
+#line 10
+testRunner.Then("I should see \"]*>.*?Create new type\"");
+#line 11
+testRunner.When("I go to \"Admin/ContentTypes/Create\"");
+#line hidden
+ TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] {
+ "name",
+ "value"});
+ table1.AddRow(new string[] {
+ "DisplayName",
+ "Event"});
+ table1.AddRow(new string[] {
+ "Name",
+ "Event"});
+#line 12
+testRunner.And("I fill in", ((string)(null)), table1);
+#line 16
+testRunner.And("I hit \"Create\"");
+#line 17
+testRunner.And("I go to \"Admin/ContentTypes/\"");
+#line 18
+testRunner.Then("I should see \"Event\"");
+#line hidden
+ testRunner.CollectScenarioErrors();
+ }
+
+ [NUnit.Framework.TestAttribute()]
+ [NUnit.Framework.DescriptionAttribute("I can\'t create a content type with an already existing name")]
+ public virtual void ICanTCreateAContentTypeWithAnAlreadyExistingName()
+ {
+ TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can\'t create a content type with an already existing name", ((string[])(null)));
+#line 20
+this.ScenarioSetup(scenarioInfo);
+#line 21
+testRunner.Given("I have installed Orchard");
+#line 22
+testRunner.And("I have installed \"Orchard.ContentTypes\"");
+#line 23
+testRunner.When("I go to \"Admin/ContentTypes/Create\"");
+#line hidden
+ TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
+ "name",
+ "value"});
+ table2.AddRow(new string[] {
+ "DisplayName",
+ "Event"});
+ table2.AddRow(new string[] {
+ "Name",
+ "Event"});
+#line 24
+testRunner.And("I fill in", ((string)(null)), table2);
+#line 28
+testRunner.And("I hit \"Create\"");
+#line 29
+testRunner.And("I go to \"Admin/ContentTypes/\"");
+#line 30
+testRunner.Then("I should see \"Event\"");
+#line 31
+testRunner.When("I go to \"Admin/ContentTypes/Create\"");
+#line hidden
+ TechTalk.SpecFlow.Table table3 = new TechTalk.SpecFlow.Table(new string[] {
+ "name",
+ "value"});
+ table3.AddRow(new string[] {
+ "DisplayName",
+ "Event"});
+ table3.AddRow(new string[] {
+ "Name",
+ "Event-2"});
+#line 32
+testRunner.And("I fill in", ((string)(null)), table3);
+#line 36
+testRunner.And("I hit \"Create\"");
+#line 37
+testRunner.Then("I should see \"
]*>.*?New Content Type.*?
\"");
+#line 38
+testRunner.And("I should see \"validation-summary-errors\"");
+#line hidden
+ testRunner.CollectScenarioErrors();
+ }
+
+ [NUnit.Framework.TestAttribute()]
+ [NUnit.Framework.DescriptionAttribute("I can\'t create a content type with an already existing technical name")]
+ public virtual void ICanTCreateAContentTypeWithAnAlreadyExistingTechnicalName()
+ {
+ TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can\'t create a content type with an already existing technical name", ((string[])(null)));
+#line 40
+this.ScenarioSetup(scenarioInfo);
+#line 41
+testRunner.Given("I have installed Orchard");
+#line 42
+testRunner.And("I have installed \"Orchard.ContentTypes\"");
+#line 43
+testRunner.When("I go to \"Admin/ContentTypes/Create\"");
+#line hidden
+ TechTalk.SpecFlow.Table table4 = new TechTalk.SpecFlow.Table(new string[] {
+ "name",
+ "value"});
+ table4.AddRow(new string[] {
+ "DisplayName",
+ "Dinner"});
+ table4.AddRow(new string[] {
+ "Name",
+ "Dinner"});
+#line 44
+testRunner.And("I fill in", ((string)(null)), table4);
+#line 48
+testRunner.And("I hit \"Create\"");
+#line 49
+testRunner.And("I go to \"Admin/ContentTypes/\"");
+#line 50
+testRunner.Then("I should see \"Dinner\"");
+#line 51
+testRunner.When("I go to \"Admin/ContentTypes/Create\"");
+#line hidden
+ TechTalk.SpecFlow.Table table5 = new TechTalk.SpecFlow.Table(new string[] {
+ "name",
+ "value"});
+ table5.AddRow(new string[] {
+ "DisplayName",
+ "Dinner2"});
+ table5.AddRow(new string[] {
+ "Name",
+ "Dinner"});
+#line 52
+testRunner.And("I fill in", ((string)(null)), table5);
+#line 56
+testRunner.And("I hit \"Create\"");
+#line 57
+testRunner.Then("I should see \"
]*>.*?New Content Type.*?
\"");
+#line 58
+testRunner.And("I should see \"validation-summary-errors\"");
+#line hidden
+ testRunner.CollectScenarioErrors();
+ }
+
+ [NUnit.Framework.TestAttribute()]
+ [NUnit.Framework.DescriptionAttribute("I can\'t rename a content type with an already existing name")]
+ public virtual void ICanTRenameAContentTypeWithAnAlreadyExistingName()
+ {
+ TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can\'t rename a content type with an already existing name", ((string[])(null)));
+#line 60
+this.ScenarioSetup(scenarioInfo);
+#line 61
+testRunner.Given("I have installed Orchard");
+#line 62
+testRunner.And("I have installed \"Orchard.ContentTypes\"");
+#line 63
+testRunner.When("I go to \"Admin/ContentTypes/Create\"");
+#line hidden
+ TechTalk.SpecFlow.Table table6 = new TechTalk.SpecFlow.Table(new string[] {
+ "name",
+ "value"});
+ table6.AddRow(new string[] {
+ "DisplayName",
+ "Dinner"});
+ table6.AddRow(new string[] {
+ "Name",
+ "Dinner"});
+#line 64
+testRunner.And("I fill in", ((string)(null)), table6);
+#line 68
+testRunner.And("I hit \"Create\"");
+#line 69
+testRunner.And("I go to \"Admin/ContentTypes/\"");
+#line 70
+testRunner.Then("I should see \"Dinner\"");
+#line 71
+testRunner.When("I go to \"Admin/ContentTypes/Create\"");
+#line hidden
+ TechTalk.SpecFlow.Table table7 = new TechTalk.SpecFlow.Table(new string[] {
+ "name",
+ "value"});
+ table7.AddRow(new string[] {
+ "DisplayName",
+ "Event"});
+ table7.AddRow(new string[] {
+ "Name",
+ "Event"});
+#line 72
+testRunner.And("I fill in", ((string)(null)), table7);
+#line 76
+testRunner.And("I hit \"Create\"");
+#line 77
+testRunner.And("I go to \"Admin/ContentTypes/\"");
+#line 78
+testRunner.Then("I should see \"Event\"");
+#line 79
+testRunner.When("I go to \"Admin/ContentTypes/Edit/Dinner\"");
+#line hidden
+ TechTalk.SpecFlow.Table table8 = new TechTalk.SpecFlow.Table(new string[] {
+ "name",
+ "value"});
+ table8.AddRow(new string[] {
+ "DisplayName",
+ "Event"});
+#line 80
+testRunner.And("I fill in", ((string)(null)), table8);
+#line 83
+testRunner.And("I hit \"Save\"");
+#line 84
+testRunner.Then("I should see \"validation-summary-errors\"");
+#line hidden
+ testRunner.CollectScenarioErrors();
+ }
+ }
+}
+#endregion
diff --git a/src/Orchard.Specs/Orchard.Specs.csproj b/src/Orchard.Specs/Orchard.Specs.csproj
index 748a34584..ef1f40764 100644
--- a/src/Orchard.Specs/Orchard.Specs.csproj
+++ b/src/Orchard.Specs/Orchard.Specs.csproj
@@ -142,6 +142,11 @@
TrueTrue
+
+ ContentTypes.feature
+ True
+ True
+ SiteCompilation.feature
@@ -228,6 +233,10 @@
SpecFlowSingleFileGeneratorContentRights.feature.cs
+
+ SpecFlowSingleFileGenerator
+ ContentTypes.feature.cs
+ SpecFlowSingleFileGeneratorSiteCompilation.feature.cs
diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Controllers/AdminController.cs
index f4d408d2e..61cc18316 100644
--- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Controllers/AdminController.cs
+++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Controllers/AdminController.cs
@@ -47,8 +47,12 @@ namespace Orchard.ContentTypes.Controllers {
if(String.IsNullOrWhiteSpace(viewModel.DisplayName)) {
ModelState.AddModelError("DisplayName", T("The Content Type name can't be empty.").ToString());
}
+
+ if ( _contentDefinitionService.GetTypes().Any(t => String.Equals(t.Name.Trim(), viewModel.Name.Trim(), StringComparison.OrdinalIgnoreCase)) ) {
+ ModelState.AddModelError("Name", T("A type with the same technical name already exists.").ToString());
+ }
- if(_contentDefinitionService.GetTypes().Any(t => t.DisplayName == viewModel.DisplayName)) {
+ if ( _contentDefinitionService.GetTypes().Any(t => String.Equals(t.DisplayName.Trim(), viewModel.DisplayName.Trim(), StringComparison.OrdinalIgnoreCase)) ) {
ModelState.AddModelError("DisplayName", T("A type with the same name already exists.").ToString());
}
@@ -57,13 +61,19 @@ namespace Orchard.ContentTypes.Controllers {
return View(viewModel);
}
- var typeViewModel = _contentDefinitionService.AddType(viewModel);
+ var contentTypeDefinition = _contentDefinitionService.AddType(viewModel.Name, viewModel.DisplayName);
+ var typeViewModel = new EditTypeViewModel(contentTypeDefinition);
+
Services.Notifier.Information(T("The \"{0}\" content type has been created.", typeViewModel.DisplayName));
return RedirectToAction("Edit", new { id = typeViewModel.Name });
}
+ public ActionResult ContentTypeName(string displayName) {
+ return Json(_contentDefinitionService.GenerateName(displayName));
+ }
+
public ActionResult Edit(string id) {
if (!Services.Authorizer.Authorize(Permissions.CreateContentTypes, T("Not allowed to edit a content type.")))
return new HttpUnauthorizedResult();
@@ -90,9 +100,18 @@ namespace Orchard.ContentTypes.Controllers {
TryUpdateModel(edited);
typeViewModel.DisplayName = edited.DisplayName;
+ if ( String.IsNullOrWhiteSpace(typeViewModel.DisplayName) ) {
+ ModelState.AddModelError("DisplayName", T("The Content Type name can't be empty.").ToString());
+ }
+
+ if ( _contentDefinitionService.GetTypes().Any(t => String.Equals(t.DisplayName.Trim(), typeViewModel.DisplayName.Trim(), StringComparison.OrdinalIgnoreCase) && !String.Equals(t.Name, id)) ) {
+ ModelState.AddModelError("DisplayName", T("A type with the same name already exists.").ToString());
+ }
+
if (!ModelState.IsValid)
return View(typeViewModel);
+
_contentDefinitionService.AlterType(typeViewModel, this);
if (!ModelState.IsValid) {
diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs
index 9c3d936af..de42386e3 100644
--- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs
+++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs
@@ -65,18 +65,24 @@ namespace Orchard.ContentTypes.Services {
return viewModel;
}
- public EditTypeViewModel AddType(CreateTypeViewModel typeViewModel) {
- var name = GenerateName(typeViewModel.DisplayName);
+ public ContentTypeDefinition AddType(string name, string displayName) {
+ if(String.IsNullOrWhiteSpace(displayName)) {
+ throw new ArgumentException("displayName");
+ }
- while (_contentDefinitionManager.GetTypeDefinition(name) != null)
+ if(String.IsNullOrWhiteSpace(name)) {
+ name = GenerateName(displayName);
+ }
+
+ while ( _contentDefinitionManager.GetTypeDefinition(name) != null )
name = VersionName(name);
- var contentTypeDefinition = new ContentTypeDefinition(name, typeViewModel.DisplayName);
+ var contentTypeDefinition = new ContentTypeDefinition(name, displayName);
_contentDefinitionManager.StoreTypeDefinition(contentTypeDefinition);
_contentDefinitionManager.AlterTypeDefinition(name,
cfg => cfg.Creatable().Draftable());
- return new EditTypeViewModel(contentTypeDefinition);
+ return contentTypeDefinition;
}
public void AlterType(EditTypeViewModel typeViewModel, IUpdateModel updateModel) {
@@ -210,20 +216,21 @@ namespace Orchard.ContentTypes.Services {
}
//gratuitously stolen from the RoutableService
- private static string GenerateName(string displayName) {
- if (string.IsNullOrWhiteSpace(displayName))
- return "";
+ public string GenerateName(string name) {
+ if ( string.IsNullOrWhiteSpace(name) )
+ return String.Empty;
- var name = displayName;
- //todo: might need to be made more restrictive depending on how name is used (like as an XML node name, for instance)
- var dissallowed = new Regex(@"[/:?#\[\]@!$&'()*+,;=\s]+");
+ var dissallowed = new Regex(@"[/:?#\[\]@!$&'()*+,;=\s\""<>]+");
- name = dissallowed.Replace(name, "-");
- name = name.Trim('-');
+ name = dissallowed.Replace(name, String.Empty);
+ name = name.Trim();
if (name.Length > 128)
name = name.Substring(0, 128);
+ while ( _contentDefinitionManager.GetTypeDefinition(name) != null )
+ name = VersionName(name);
+
return name;
}
diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/IContentDefinitionService.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/IContentDefinitionService.cs
index 70c59e4a7..44fc6b8ae 100644
--- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/IContentDefinitionService.cs
+++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/IContentDefinitionService.cs
@@ -1,17 +1,19 @@
using System.Collections.Generic;
using Orchard.ContentManagement;
using Orchard.ContentManagement.MetaData;
+using Orchard.ContentManagement.MetaData.Models;
using Orchard.ContentTypes.ViewModels;
namespace Orchard.ContentTypes.Services {
public interface IContentDefinitionService : IDependency {
IEnumerable GetTypes();
EditTypeViewModel GetType(string name);
- EditTypeViewModel AddType(CreateTypeViewModel typeViewModel);
+ ContentTypeDefinition AddType(string name, string displayName);
void AlterType(EditTypeViewModel typeViewModel, IUpdateModel updater);
void RemoveType(string name);
void AddPartToType(string partName, string typeName);
void RemovePartFromType(string partName, string typeName);
+ string GenerateName(string displayName);
IEnumerable GetParts();
EditPartViewModel GetPart(string name);
diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/ViewModels/CreateTypeViewModel.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/ViewModels/CreateTypeViewModel.cs
index 29a57e6e6..a53768699 100644
--- a/src/Orchard.Web/Modules/Orchard.ContentTypes/ViewModels/CreateTypeViewModel.cs
+++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/ViewModels/CreateTypeViewModel.cs
@@ -1,5 +1,6 @@
namespace Orchard.ContentTypes.ViewModels {
public class CreateTypeViewModel {
public string DisplayName { get; set; }
+ public string Name { get; set; }
}
}
diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/Create.cshtml b/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/Create.cshtml
index fe3758232..847f21fa9 100644
--- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/Create.cshtml
+++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/Create.cshtml
@@ -1,10 +1,40 @@
@model Orchard.ContentTypes.ViewModels.CreateTypeViewModel
+