mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-20 19:03:25 +08:00
Merge branch '1.7.x' into 1.x
Conflicts: src/Orchard.Web/Modules/Orchard.AntiSpam/Drivers/ReCaptchaPartDriver.cs src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/AdminController.cs src/Orchard.Web/Modules/Orchard.Search/Orchard.Search.csproj
This commit is contained in:
@@ -20,7 +20,7 @@ namespace Orchard.Tests.Modules.Warmup {
|
||||
|
||||
[Test]
|
||||
public void StatusCodeShouldBe404ForUnexistingResources() {
|
||||
var download = _webDownloader.Download("http://www.microsoft.com/yepyep");
|
||||
var download = _webDownloader.Download("http://orchardproject.net/yepyep");
|
||||
Assert.That(download, Is.Not.Null);
|
||||
Assert.That(download.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
|
||||
Assert.That(download.Content, Is.Null);
|
||||
@@ -28,7 +28,7 @@ namespace Orchard.Tests.Modules.Warmup {
|
||||
|
||||
[Test]
|
||||
public void StatusCodeShouldBe200ForValidRequests() {
|
||||
var download = _webDownloader.Download("http://www.microsoft.com/");
|
||||
var download = _webDownloader.Download("http://orchardproject.net/");
|
||||
Assert.That(download, Is.Not.Null);
|
||||
Assert.That(download.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
Assert.That(download.Content, Is.Not.Empty);
|
||||
|
@@ -121,7 +121,10 @@ namespace Orchard.Core.Contents.Controllers {
|
||||
}
|
||||
|
||||
private IEnumerable<ContentTypeDefinition> GetCreatableTypes(bool andContainable) {
|
||||
return _contentDefinitionManager.ListTypeDefinitions().Where(ctd => ctd.Settings.GetModel<ContentTypeSettings>().Creatable && (!andContainable || ctd.Parts.Any(p => p.PartDefinition.Name == "ContainablePart")));
|
||||
return _contentDefinitionManager.ListTypeDefinitions().Where(ctd =>
|
||||
Services.Authorizer.Authorize(Permissions.EditContent, _contentManager.New(ctd.Name)) &&
|
||||
ctd.Settings.GetModel<ContentTypeSettings>().Creatable &&
|
||||
(!andContainable || ctd.Parts.Any(p => p.PartDefinition.Name == "ContainablePart")));
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("List")]
|
||||
|
@@ -6,9 +6,9 @@
|
||||
Layout.Title = T("Navigation").ToString();
|
||||
Style.Include("navigation-admin.css");
|
||||
|
||||
Script.Require("jQueryUI_Sortable");
|
||||
Script.Include("jquery.mjs.nestedSortable.js");
|
||||
Script.Include("navigation-admin.js");
|
||||
Script.Require("jQueryUI_Sortable").AtFoot();
|
||||
Script.Include("jquery.mjs.nestedSortable.js").AtFoot();
|
||||
Script.Include("navigation-admin.js").AtFoot();
|
||||
}
|
||||
|
||||
<div id="save-message" class="message message-Warning">@T("You need to hit \"Save All\" in order to save your changes.")</div>
|
||||
|
@@ -5,12 +5,14 @@
|
||||
}
|
||||
<fieldset>
|
||||
@Html.EditorFor(m => m.OnAdminMenu)
|
||||
<label for="OnAdminMenu" class="forcheckbox">@T("Show on admin menu")</label>
|
||||
<div data-controllerid="OnAdminMenu" class="">
|
||||
<label for="AdminMenuText">@T("Menu text")</label>
|
||||
<label for="@Html.FieldIdFor(m => m.OnAdminMenu)" class="forcheckbox">@T("Show on admin menu")</label>
|
||||
<div data-controllerid="@Html.FieldIdFor(m => m.OnAdminMenu)" class="">
|
||||
<label for="@Html.FieldIdFor(m => m.AdminMenuText)">@T("Menu text")</label>
|
||||
@Html.TextBoxFor(m => m.AdminMenuText, new { @class = "text single-line" })
|
||||
<span class="hint">@T("The text that should appear in the menu.")</span>
|
||||
|
||||
<label for="AdminMenuPosition">@T("Position")</label>
|
||||
@Html.TextBoxFor(m => m.AdminMenuPosition, new { @class = "text single-line" })
|
||||
<label for="@Html.FieldIdFor(m => m.AdminMenuPosition)">@T("Position")</label>
|
||||
@Html.TextBoxFor(m => m.AdminMenuPosition, new { @class = "text small" })
|
||||
<span class="hint">@T("The position in the menu.")</span>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
@@ -263,26 +263,24 @@ namespace Orchard.Core.Shapes {
|
||||
IDictionary<string, string> attributes = Shape.Attributes;
|
||||
var zoneWrapper = GetTagBuilder("div", id, classes, attributes);
|
||||
Output.Write(zoneWrapper.ToString(TagRenderMode.StartTag));
|
||||
foreach (var item in ordered_hack(Shape))
|
||||
foreach (var item in Order(Shape))
|
||||
Output.Write(Display(item));
|
||||
Output.Write(zoneWrapper.ToString(TagRenderMode.EndTag));
|
||||
}
|
||||
|
||||
[Shape]
|
||||
public void ContentZone(dynamic Display, dynamic Shape, TextWriter Output) {
|
||||
foreach (var item in ordered_hack(Shape))
|
||||
foreach (var item in Order(Shape))
|
||||
Output.Write(Display(item));
|
||||
}
|
||||
|
||||
[Shape]
|
||||
public void DocumentZone(dynamic Display, dynamic Shape, TextWriter Output) {
|
||||
foreach (var item in ordered_hack(Shape))
|
||||
foreach (var item in Order(Shape))
|
||||
Output.Write(Display(item));
|
||||
}
|
||||
|
||||
#region ordered_hack
|
||||
|
||||
private static IEnumerable<dynamic> ordered_hack(dynamic shape) {
|
||||
public static IEnumerable<dynamic> Order(dynamic shape) {
|
||||
IEnumerable<dynamic> unordered = shape;
|
||||
if (unordered == null || unordered.Count() < 2)
|
||||
return shape;
|
||||
@@ -317,8 +315,6 @@ namespace Orchard.Core.Shapes {
|
||||
return ordering.Select(ordered => ordered.item).ToList();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
[Shape]
|
||||
public void HeadScripts(dynamic Display, TextWriter Output) {
|
||||
WriteResources(Display, Output, "script", ResourceLocation.Head, null);
|
||||
@@ -618,7 +614,7 @@ namespace Orchard.Core.Shapes {
|
||||
|
||||
IEnumerable<string> classes = Shape.Classes;
|
||||
IDictionary<string, string> attributes = Shape.Attributes;
|
||||
attributes.Add("href", action);
|
||||
attributes["href"] = action;
|
||||
string id = Shape.Id;
|
||||
var tag = GetTagBuilder("a", id, classes, attributes);
|
||||
tag.InnerHtml = EncodeOrDisplay(Value, Display, Html).ToString();
|
||||
|
@@ -100,7 +100,7 @@ namespace Lucene.Models {
|
||||
switch(_typeCode) {
|
||||
case TypeCode.String:
|
||||
if(_removeTags) {
|
||||
_stringValue = _stringValue.RemoveTags();
|
||||
_stringValue = _stringValue.RemoveTags(true);
|
||||
}
|
||||
Fields.Add(new Field(_name, _stringValue ?? String.Empty,
|
||||
_store ? Field.Store.YES : Field.Store.NO,
|
||||
|
@@ -9,6 +9,7 @@ using Orchard.AntiSpam.ViewModels;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Logging;
|
||||
using Orchard.UI.Admin;
|
||||
using Orchard.UI.Notify;
|
||||
|
||||
@@ -25,10 +26,11 @@ namespace Orchard.AntiSpam.Drivers {
|
||||
_notifier = notifier;
|
||||
_workContextAccessor = workContextAccessor;
|
||||
T = NullLocalizer.Instance;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
|
||||
public ILogger Logger { get; set; }
|
||||
protected override DriverResult Editor(ReCaptchaPart part, dynamic shapeHelper) {
|
||||
var workContext = _workContextAccessor.GetContext();
|
||||
|
||||
@@ -70,6 +72,7 @@ namespace Orchard.AntiSpam.Drivers {
|
||||
if(updater.TryUpdateModel(submitViewModel, String.Empty, null, null)) {
|
||||
var context = workContext.HttpContext;
|
||||
|
||||
try {
|
||||
var result = ExecuteValidateRequest(
|
||||
settings.PrivateKey,
|
||||
context.Request.ServerVariables["REMOTE_ADDR"],
|
||||
@@ -82,6 +85,11 @@ namespace Orchard.AntiSpam.Drivers {
|
||||
updater.AddModelError("", T("The text you entered in the Captcha field does not match the image"));
|
||||
}
|
||||
}
|
||||
catch(Exception e) {
|
||||
Logger.Error(e, "An unexcepted error occured while submitting a reCaptcha");
|
||||
updater.AddModelError("Parts_ReCaptcha_Fields", T("There was an error while validating the Captcha image"));
|
||||
}
|
||||
}
|
||||
|
||||
return Editor(part, shapeHelper);
|
||||
}
|
||||
|
@@ -48,6 +48,10 @@ namespace Orchard.Azure.Services.Caching.Output {
|
||||
}
|
||||
|
||||
public void Set(string key, CacheItem cacheItem) {
|
||||
if (cacheItem.ValidFor <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.Debug("Set() invoked with key='{0}' in region '{1}'.", key, _regionAlphaNumeric);
|
||||
_cache.Put(key, cacheItem, TimeSpan.FromSeconds(cacheItem.ValidFor), _regionAlphaNumeric);
|
||||
}
|
||||
|
@@ -108,11 +108,15 @@ namespace Orchard.Comments.Controllers {
|
||||
// if the user who submitted the comment has the right to moderate, don't make this comment moderated
|
||||
if (Services.Authorizer.Authorize(Permissions.ManageComments)) {
|
||||
commentPart.Status = CommentStatus.Approved;
|
||||
Services.Notifier.Information(T("Your comment has been posted."));
|
||||
}
|
||||
else {
|
||||
Services.Notifier.Information(T("Your comment will appear after the site administrator approves it."));
|
||||
}
|
||||
}
|
||||
else {
|
||||
Services.Notifier.Information(T("Your comment has been posted."));
|
||||
}
|
||||
}
|
||||
else {
|
||||
Services.TransactionManager.Cancel();
|
||||
|
@@ -52,12 +52,32 @@
|
||||
(function ($) {
|
||||
|
||||
var assignPositions = function () {
|
||||
var position = 1;
|
||||
$('.position').each(function() {
|
||||
$(this).val(position++);
|
||||
var position = 0;
|
||||
$('.type').each(function () {
|
||||
var input = $(this);
|
||||
reAssignIdName(input, position); // type
|
||||
|
||||
input = input.next();
|
||||
reAssignIdName(input, position); // differentiator
|
||||
|
||||
input = input.next();
|
||||
reAssignIdName(input, position); // zone
|
||||
|
||||
input = input.next();
|
||||
reAssignIdName(input, position); // position
|
||||
|
||||
input.val(++position);
|
||||
});
|
||||
};
|
||||
|
||||
var reAssignIdName = function (input, pos) {
|
||||
var name = input.attr('name');
|
||||
input.attr('name', name.replace(new RegExp("\\[.*\\]", 'gi'), '[' + pos + ']'));
|
||||
|
||||
var id = input.attr('id');
|
||||
input.attr('id', id.replace(new RegExp('_.*__', 'i'), '_' + pos + '__'));
|
||||
};
|
||||
|
||||
assignPositions();
|
||||
|
||||
var startPos;
|
||||
|
@@ -5,6 +5,7 @@ using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.Environment.Descriptor;
|
||||
using Orchard.FileSystems.AppData;
|
||||
@@ -139,31 +140,48 @@ namespace Orchard.ImportExport.Services {
|
||||
}
|
||||
|
||||
private XElement ExportSiteSettings() {
|
||||
var settings = new XElement("Settings");
|
||||
var hasSetting = false;
|
||||
var siteContentItem = _orchardServices.WorkContext.CurrentSite.ContentItem;
|
||||
var exportedElements = ExportContentItem(siteContentItem).Elements().ToList();
|
||||
|
||||
foreach (var sitePart in _orchardServices.WorkContext.CurrentSite.ContentItem.Parts) {
|
||||
var setting = new XElement(sitePart.PartDefinition.Name);
|
||||
foreach (var contentPart in siteContentItem.Parts) {
|
||||
var exportedElement = exportedElements.FirstOrDefault(element => element.Name == contentPart.PartDefinition.Name);
|
||||
|
||||
//Get all simple attributes if exported element is null
|
||||
//Get exclude the simple attributes that already exist if element is not null
|
||||
var simpleAttributes =
|
||||
ExportSettingsPartAttributes(contentPart)
|
||||
.Where(attribute => exportedElement == null || exportedElement.Attributes().All(xAttribute => xAttribute.Name != attribute.Name))
|
||||
.ToList();
|
||||
|
||||
if (simpleAttributes.Any()) {
|
||||
if (exportedElement == null) {
|
||||
exportedElement = new XElement(contentPart.PartDefinition.Name);
|
||||
exportedElements.Add(exportedElement);
|
||||
}
|
||||
|
||||
exportedElement.Add(simpleAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
return new XElement("Settings", exportedElements);
|
||||
}
|
||||
|
||||
private IEnumerable<XAttribute> ExportSettingsPartAttributes(ContentPart sitePart) {
|
||||
foreach (var property in sitePart.GetType().GetProperties()) {
|
||||
var propertyType = property.PropertyType;
|
||||
|
||||
// Supported types (we also know they are not indexed properties).
|
||||
if (propertyType == typeof(string) || propertyType == typeof(bool) || propertyType == typeof(int)) {
|
||||
// Exclude read-only properties.
|
||||
if (property.GetSetMethod() != null) {
|
||||
setting.SetAttributeValue(property.Name, property.GetValue(sitePart, null));
|
||||
hasSetting = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
var value = property.GetValue(sitePart, null);
|
||||
if (value == null)
|
||||
continue;
|
||||
|
||||
if (hasSetting) {
|
||||
settings.Add(setting);
|
||||
hasSetting = false;
|
||||
yield return new XAttribute(property.Name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
private XElement ExportData(IEnumerable<string> contentTypes, IEnumerable<ContentItem> contentItems, int? batchSize) {
|
||||
|
@@ -39,6 +39,8 @@ namespace Orchard.MediaLibrary.Controllers {
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public ActionResult Index(string folderPath = "", bool dialog = false) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent, T("Cannot view media")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
// let other modules enhance the ui by providing custom navigation and actions
|
||||
var explorer = Services.ContentManager.New("MediaLibraryExplorer");
|
||||
@@ -67,6 +69,8 @@ namespace Orchard.MediaLibrary.Controllers {
|
||||
}
|
||||
|
||||
public ActionResult Import(string folderPath) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent, T("Cannot import media")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var mediaProviderMenu = _navigationManager.BuildMenu("mediaproviders");
|
||||
var imageSets = _navigationManager.BuildImageSets("mediaproviders");
|
||||
@@ -83,8 +87,11 @@ namespace Orchard.MediaLibrary.Controllers {
|
||||
|
||||
[Themed(false)]
|
||||
public ActionResult MediaItems(string folderPath, int skip = 0, int count = 0, string order = "created", string mediaType = "") {
|
||||
var mediaParts = _mediaLibraryService.GetMediaContentItems(folderPath, skip, count, order, mediaType, VersionOptions.Latest);
|
||||
var mediaPartsCount = _mediaLibraryService.GetMediaContentItemsCount(folderPath, mediaType, VersionOptions.Latest);
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent, T("Cannot view media")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var mediaParts = _mediaLibraryService.GetMediaContentItems(folderPath, skip, count, order, mediaType);
|
||||
var mediaPartsCount = _mediaLibraryService.GetMediaContentItemsCount(folderPath, mediaType);
|
||||
|
||||
var mediaItems = mediaParts.Select(x => new MediaManagerMediaItemViewModel {
|
||||
MediaPart = x,
|
||||
@@ -115,8 +122,12 @@ namespace Orchard.MediaLibrary.Controllers {
|
||||
|
||||
[Themed(false)]
|
||||
public ActionResult RecentMediaItems(int skip = 0, int count = 0, string order = "created", string mediaType = "") {
|
||||
var mediaParts = _mediaLibraryService.GetMediaContentItems(skip, count, order, mediaType, VersionOptions.Latest);
|
||||
var mediaPartsCount = _mediaLibraryService.GetMediaContentItemsCount(mediaType, VersionOptions.Latest);
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent, T("Cannot view media")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var mediaParts = _mediaLibraryService.GetMediaContentItems(skip, count, order, mediaType);
|
||||
var mediaPartsCount = _mediaLibraryService.GetMediaContentItemsCount(mediaType);
|
||||
|
||||
|
||||
var mediaItems = mediaParts.Select(x => new MediaManagerMediaItemViewModel {
|
||||
MediaPart = x,
|
||||
@@ -138,7 +149,7 @@ namespace Orchard.MediaLibrary.Controllers {
|
||||
if (contentItem == null)
|
||||
return HttpNotFound();
|
||||
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent, contentItem, T("Cannot edit media")))
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent, contentItem, T("Cannot view media")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
dynamic model = Services.ContentManager.BuildDisplay(contentItem, displayType);
|
||||
|
@@ -15,7 +15,7 @@ namespace Orchard.MediaLibrary {
|
||||
if (!(filterContext.Result is ViewResult) || !UI.Admin.AdminFilter.IsApplied(filterContext.RequestContext))
|
||||
return;
|
||||
_resourceManager.Include("stylesheet", "~/Modules/Orchard.MediaLibrary/Styles/dialog-mode.css", null);
|
||||
_resourceManager.Include("script", "~/Modules/Orchard.MediaLibrary/Scripts/modal-window.js", null);
|
||||
_resourceManager.Include("script", "~/Modules/Orchard.MediaLibrary/Scripts/modal-window.js", null).AtFoot();
|
||||
}
|
||||
|
||||
public void OnResultExecuted(ResultExecutedContext filterContext) {
|
||||
|
@@ -3,13 +3,13 @@
|
||||
@{
|
||||
var viewModel = Model;
|
||||
|
||||
Script.Require("ShapesBase");
|
||||
Script.Require("ShapesBase").AtFoot();
|
||||
Style.Require("MediaManagerAdmin");
|
||||
Script.Require("jQuery");
|
||||
Script.Require("jQueryUI_Droppable");
|
||||
Script.Include("knockout-2.3.0.js");
|
||||
Script.Include("history.js");
|
||||
Script.Include("media-library.js");
|
||||
Script.Require("jQuery").AtFoot();
|
||||
Script.Require("jQueryUI_Droppable").AtFoot();
|
||||
Script.Include("knockout-2.3.0.js").AtFoot();
|
||||
Script.Include("history.js").AtFoot();
|
||||
Script.Include("media-library.js").AtFoot();
|
||||
Style.Require("FontAwesome");
|
||||
|
||||
Layout.Title = T("Media Library");
|
||||
|
@@ -4,15 +4,15 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
@{
|
||||
Script.Require("jQuery");
|
||||
Script.Require("jQueryUI");
|
||||
Script.Require("jQuery").AtFoot();
|
||||
Script.Require("jQueryUI").AtFoot();
|
||||
|
||||
Style.Include("orchard-medialibrary-admin.css");
|
||||
Style.Include("orchard-mediaproviders-admin.css");
|
||||
Style.Include("orchard-clientstorage-admin.css");
|
||||
|
||||
Script.Require("jQueryFileUpload");
|
||||
Script.Include("knockout-2.3.0.js");
|
||||
Script.Require("jQueryFileUpload").AtFoot();
|
||||
Script.Include("knockout-2.3.0.js").AtFoot();
|
||||
}
|
||||
|
||||
@Display.Metas()
|
||||
|
@@ -7,7 +7,7 @@
|
||||
Script.Require("jQueryUI_Sortable").AtFoot();
|
||||
Style.Include("media-library-picker-admin.css");
|
||||
|
||||
Script.Require("jQueryColorBox");
|
||||
Script.Require("jQueryColorBox").AtFoot();
|
||||
Style.Require("jQueryColorBox");
|
||||
|
||||
var settings = Model.Field.PartFieldDefinition.Settings.GetModel<MediaLibraryPickerFieldSettings>();
|
||||
|
@@ -4,7 +4,7 @@
|
||||
MediaPart mediaPart = Model.ContentItem.MediaPart;
|
||||
var contentTypeClassName = mediaPart.ContentItem.ContentType.HtmlClassify();
|
||||
}
|
||||
<article class="media-item media-item-summary-admin @contentTypeClassName">
|
||||
<article class="media-item media-item-summary-admin summary @contentTypeClassName" itemid="@mediaPart.Id">
|
||||
<header>
|
||||
@Display(Model.Header)
|
||||
@if (Model.Meta != null) {
|
||||
|
@@ -4,8 +4,8 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
@{
|
||||
Script.Require("jQuery");
|
||||
Script.Require("jQueryUI");
|
||||
Script.Require("jQuery").AtFoot();
|
||||
Script.Require("jQueryUI").AtFoot();
|
||||
|
||||
Style.Include("orchard-medialibrary-admin.css");
|
||||
Style.Include("orchard-mediaproviders-admin.css");
|
||||
|
@@ -8,8 +8,8 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
@{
|
||||
Script.Require("jQuery");
|
||||
Script.Include("knockout-2.3.0.js");
|
||||
Script.Require("jQuery").AtFoot();
|
||||
Script.Include("knockout-2.3.0.js").AtFoot();
|
||||
|
||||
Style.Include("orchard-mediaproviders-admin.css");
|
||||
Style.Include("orchard-websearch-admin.css");
|
||||
|
@@ -8,7 +8,7 @@
|
||||
@{
|
||||
Style.Require("ModulesAdmin");
|
||||
Style.Require("Switchable");
|
||||
Script.Require("Switchable");
|
||||
Script.Require("Switchable").AtFoot();
|
||||
Script.Include("features.admin.js", "features.admin.min.js").AtFoot();
|
||||
|
||||
Layout.Title = T("Modules").ToString();
|
||||
|
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -38,8 +37,6 @@ namespace Orchard.OutputCache.Filters {
|
||||
private readonly ICacheControlStrategy _cacheControlStrategy;
|
||||
private Stream _previousFilter;
|
||||
|
||||
private const string RefreshKey = "__r";
|
||||
|
||||
public OutputCacheFilter(
|
||||
ICacheManager cacheManager,
|
||||
IOutputCacheStorageProvider cacheStorageProvider,
|
||||
@@ -51,7 +48,8 @@ namespace Orchard.OutputCache.Filters {
|
||||
ICacheService cacheService,
|
||||
ISignals signals,
|
||||
ShellSettings shellSettings,
|
||||
ICacheControlStrategy cacheControlStrategy) {
|
||||
ICacheControlStrategy cacheControlStrategy
|
||||
) {
|
||||
_cacheManager = cacheManager;
|
||||
_cacheStorageProvider = cacheStorageProvider;
|
||||
_tagCache = tagCache;
|
||||
@@ -74,11 +72,10 @@ namespace Orchard.OutputCache.Filters {
|
||||
private bool _applyCulture;
|
||||
private string _cacheKey;
|
||||
private string _invariantCacheKey;
|
||||
private string _actionName;
|
||||
private DateTime _now;
|
||||
private string[] _varyQueryStringParameters;
|
||||
private ISet<string> _varyRequestHeaders;
|
||||
|
||||
private bool _transformRedirect;
|
||||
|
||||
private WorkContext _workContext;
|
||||
private CapturingResponseFilter _filter;
|
||||
@@ -88,8 +85,6 @@ namespace Orchard.OutputCache.Filters {
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public void OnActionExecuting(ActionExecutingContext filterContext) {
|
||||
// use the action in the cacheKey so that the same route can't return cache for different actions
|
||||
_actionName = filterContext.ActionDescriptor.ActionName;
|
||||
|
||||
// apply OutputCacheAttribute logic if defined
|
||||
var actionAttributes = filterContext.ActionDescriptor.GetCustomAttributes(typeof(OutputCacheAttribute), true);
|
||||
@@ -285,12 +280,12 @@ namespace Orchard.OutputCache.Filters {
|
||||
|
||||
// no cache content available, intercept the execution results for caching
|
||||
_previousFilter = response.Filter;
|
||||
response.Filter = _filter = new CapturingResponseFilter(response.Filter);
|
||||
response.Filter = _filter = new CapturingResponseFilter();
|
||||
}
|
||||
|
||||
public void OnActionExecuted(ActionExecutedContext filterContext) {
|
||||
// handle redirections
|
||||
TransformRedirect(filterContext);
|
||||
_transformRedirect = TransformRedirect(filterContext);
|
||||
}
|
||||
|
||||
public void OnResultExecuted(ResultExecutedContext filterContext) {
|
||||
@@ -360,7 +355,6 @@ namespace Orchard.OutputCache.Filters {
|
||||
response.Filter = null;
|
||||
response.Write(output);
|
||||
|
||||
|
||||
// check if there is a specific rule not to cache the whole route
|
||||
var configurations = _cacheService.GetRouteConfigurations();
|
||||
var route = filterContext.Controller.ControllerContext.RouteData.Route;
|
||||
@@ -373,12 +367,32 @@ namespace Orchard.OutputCache.Filters {
|
||||
return;
|
||||
}
|
||||
|
||||
// don't cache the result of a POST redirection as it could contain notifications
|
||||
if (_transformRedirect) {
|
||||
return;
|
||||
}
|
||||
|
||||
// don't cache the result if there were some notifications
|
||||
var messagesZone = _workContextAccessor.GetContext(filterContext).Layout.Zones["Messages"];
|
||||
var hasNotifications = messagesZone != null && ((IEnumerable<dynamic>)messagesZone).Any();
|
||||
if (hasNotifications) {
|
||||
return;
|
||||
}
|
||||
|
||||
// default duration of specific one ?
|
||||
var cacheDuration = configuration != null && configuration.Duration.HasValue ? configuration.Duration.Value : _cacheDuration;
|
||||
|
||||
if (cacheDuration <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// include each of the content item ids as tags for the cache entry
|
||||
var contentItemIds = _displayedContentItemHandler.GetDisplayed().Select(x => x.ToString(CultureInfo.InvariantCulture)).ToArray();
|
||||
|
||||
if (filterContext.HttpContext.Request.Url == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
_cacheItem.ContentType = response.ContentType;
|
||||
_cacheItem.StatusCode = response.StatusCode;
|
||||
_cacheItem.CachedOnUtc = _now;
|
||||
@@ -408,6 +422,8 @@ namespace Orchard.OutputCache.Filters {
|
||||
|
||||
private bool TransformRedirect(ActionExecutedContext filterContext) {
|
||||
|
||||
// removes the target of the redirection from cache after a POST
|
||||
|
||||
if (filterContext.Result == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
@@ -439,26 +455,6 @@ namespace Orchard.OutputCache.Filters {
|
||||
|
||||
_cacheService.RemoveByTag(invariantCacheKey);
|
||||
|
||||
// adding a refresh key so that the next request will not be cached
|
||||
var epIndex = redirectUrl.IndexOf('?');
|
||||
var qs = new NameValueCollection();
|
||||
if (epIndex > 0) {
|
||||
qs = HttpUtility.ParseQueryString(redirectUrl.Substring(epIndex));
|
||||
}
|
||||
|
||||
var refresh = _now.Ticks;
|
||||
qs.Remove(RefreshKey);
|
||||
|
||||
qs.Add(RefreshKey, refresh.ToString("x"));
|
||||
var querystring = "?" + string.Join("&", Array.ConvertAll(qs.AllKeys, k => string.Format("{0}={1}", HttpUtility.UrlEncode(k), HttpUtility.UrlEncode(qs[k]))));
|
||||
|
||||
if (epIndex > 0) {
|
||||
redirectUrl = redirectUrl.Substring(0, epIndex) + querystring;
|
||||
}
|
||||
else {
|
||||
redirectUrl = redirectUrl + querystring;
|
||||
}
|
||||
|
||||
filterContext.Result = new RedirectResult(redirectUrl, ((RedirectResult) filterContext.Result).Permanent);
|
||||
filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
|
||||
|
||||
@@ -539,9 +535,6 @@ namespace Orchard.OutputCache.Filters {
|
||||
// include the theme in the cache key
|
||||
keyBuilder.Append("theme=").Append(theme.ToLowerInvariant()).Append(";");
|
||||
|
||||
// include the theme in the cache key
|
||||
keyBuilder.Append("action=").Append(_actionName.ToLowerInvariant()).Append(";");
|
||||
|
||||
if (parameters != null) {
|
||||
foreach (var pair in parameters) {
|
||||
keyBuilder.AppendFormat("{0}={1};", pair.Key.ToLowerInvariant(), Convert.ToString(pair.Value).ToLowerInvariant());
|
||||
@@ -598,11 +591,9 @@ namespace Orchard.OutputCache.Filters {
|
||||
/// Captures the response stream while writing to it
|
||||
/// </summary>
|
||||
public class CapturingResponseFilter : Stream {
|
||||
// private readonly Stream _sink;
|
||||
private readonly MemoryStream _mem;
|
||||
|
||||
public CapturingResponseFilter(Stream sink) {
|
||||
// _sink = sink;
|
||||
public CapturingResponseFilter() {
|
||||
_mem = new MemoryStream();
|
||||
}
|
||||
|
||||
@@ -630,27 +621,21 @@ namespace Orchard.OutputCache.Filters {
|
||||
}
|
||||
|
||||
public override void SetLength(long length) {
|
||||
// _sink.SetLength(length);
|
||||
}
|
||||
|
||||
public override void Close() {
|
||||
// _sink.Close();
|
||||
_mem.Close();
|
||||
}
|
||||
|
||||
public override void Flush() {
|
||||
// _sink.Flush();
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count) {
|
||||
// return _sink.Read(buffer, offset, count);
|
||||
return count;
|
||||
}
|
||||
|
||||
// Override the Write method to filter Response to a file.
|
||||
public override void Write(byte[] buffer, int offset, int count) {
|
||||
//Here we will not write to the sink b/c we want to capture
|
||||
// _sink.Write(buffer, offset, count);
|
||||
|
||||
//Write out the response to the file.
|
||||
_mem.Write(buffer, 0, count);
|
||||
|
@@ -3,9 +3,7 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.OutputCache.Models;
|
||||
using Orchard;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Services;
|
||||
|
||||
namespace Orchard.OutputCache.Services {
|
||||
public class DefaultCacheStorageProvider : IOutputCacheStorageProvider {
|
||||
|
@@ -31,11 +31,8 @@ namespace Orchard.Packaging.Controllers {
|
||||
ShellSettings shellSettings,
|
||||
IOrchardServices services,
|
||||
IPackagingSourceManager packagingSourceManager,
|
||||
INotifier notifier,
|
||||
IPackageUpdateService packageUpdateService,
|
||||
IBackgroundPackageUpdateStatus backgroundPackageUpdateStatus,
|
||||
IReportsCoordinator reportsCoordinator,
|
||||
IReportsManager reportsManager,
|
||||
IShapeFactory shapeFactory) {
|
||||
|
||||
_shellSettings = shellSettings;
|
||||
@@ -45,7 +42,6 @@ namespace Orchard.Packaging.Controllers {
|
||||
|
||||
Services = services;
|
||||
Shape = shapeFactory;
|
||||
PackageUpdateService = packageUpdateService;
|
||||
|
||||
T = NullLocalizer.Instance;
|
||||
Logger = NullLogger.Instance;
|
||||
@@ -55,7 +51,6 @@ namespace Orchard.Packaging.Controllers {
|
||||
public Localizer T { get; set; }
|
||||
public ILogger Logger { get; set; }
|
||||
public dynamic Shape { get; set; }
|
||||
public IPackageUpdateService PackageUpdateService { get; set; }
|
||||
|
||||
public ActionResult ThemesUpdates(int? reportId, PagerParameters pagerParameters) {
|
||||
return PackageUpdate("ThemesUpdates", DefaultExtensionTypes.Theme, reportId, pagerParameters);
|
||||
|
@@ -311,8 +311,8 @@ namespace Orchard.Projections.Drivers {
|
||||
int layoutIndexValue;
|
||||
if (layoutIndex != null
|
||||
&& Int32.TryParse(layoutIndex, out layoutIndexValue)
|
||||
&& layoutIndexValue != -1
|
||||
&& part.Record.QueryPartRecord.Layouts.Count >= layoutIndexValue + 1)
|
||||
&& layoutIndexValue >= 0
|
||||
&& part.Record.QueryPartRecord.Layouts.Count > layoutIndexValue)
|
||||
{
|
||||
part.Record.LayoutRecord = part.Record.QueryPartRecord.Layouts[Int32.Parse(layoutIndex)];
|
||||
}
|
||||
|
@@ -1,7 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Policy;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Logging;
|
||||
using Orchard.Recipes.Models;
|
||||
@@ -11,15 +14,20 @@ using Orchard.Settings;
|
||||
namespace Orchard.Recipes.RecipeHandlers {
|
||||
public class SettingsRecipeHandler : IRecipeHandler {
|
||||
private readonly ISiteService _siteService;
|
||||
private readonly IContentManager _contentManager;
|
||||
private readonly Lazy<IEnumerable<IContentHandler>> _handlers;
|
||||
|
||||
public SettingsRecipeHandler(ISiteService siteService) {
|
||||
public SettingsRecipeHandler(ISiteService siteService, IContentManager contentManager, Lazy<IEnumerable<IContentHandler>> handlers) {
|
||||
_siteService = siteService;
|
||||
_contentManager = contentManager;
|
||||
_handlers = handlers;
|
||||
Logger = NullLogger.Instance;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
public ILogger Logger { get; set; }
|
||||
private IEnumerable<IContentHandler> Handlers { get { return _handlers.Value; } }
|
||||
|
||||
/*
|
||||
<Settings>
|
||||
@@ -33,41 +41,52 @@ namespace Orchard.Recipes.RecipeHandlers {
|
||||
return;
|
||||
}
|
||||
|
||||
var site = _siteService.GetSiteSettings();
|
||||
foreach (var element in recipeContext.RecipeStep.Step.Elements()) {
|
||||
var partName = XmlConvert.DecodeName(element.Name.LocalName);
|
||||
foreach (var contentPart in site.ContentItem.Parts) {
|
||||
if (!String.Equals(contentPart.PartDefinition.Name, partName, StringComparison.OrdinalIgnoreCase)) {
|
||||
var siteContentItem = _siteService.GetSiteSettings().ContentItem;
|
||||
|
||||
var importContentSession = new ImportContentSession(_contentManager);
|
||||
|
||||
var context = new ImportContentContext(siteContentItem, recipeContext.RecipeStep.Step, importContentSession);
|
||||
foreach (var contentHandler in Handlers) {
|
||||
contentHandler.Importing(context);
|
||||
}
|
||||
|
||||
foreach (var contentPart in siteContentItem.Parts) {
|
||||
var partElement = context.Data.Element(contentPart.PartDefinition.Name);
|
||||
if (partElement == null) {
|
||||
continue;
|
||||
}
|
||||
foreach (var attribute in element.Attributes()) {
|
||||
SetSetting(attribute, contentPart);
|
||||
}
|
||||
|
||||
ImportSettingPart(contentPart, partElement);
|
||||
}
|
||||
|
||||
foreach (var contentHandler in Handlers) {
|
||||
contentHandler.Imported(context);
|
||||
}
|
||||
|
||||
recipeContext.Executed = true;
|
||||
}
|
||||
|
||||
private static void SetSetting(XAttribute attribute, ContentPart contentPart) {
|
||||
private void ImportSettingPart(ContentPart sitePart, XElement element) {
|
||||
|
||||
foreach (var attribute in element.Attributes()) {
|
||||
var attributeName = attribute.Name.LocalName;
|
||||
var attributeValue = attribute.Value;
|
||||
var property = contentPart.GetType().GetProperty(attributeName);
|
||||
|
||||
var property = sitePart.GetType().GetProperty(attributeName);
|
||||
if (property == null) {
|
||||
throw new InvalidOperationException(string.Format("Could set setting {0} for part {1} because it was not found.", attributeName, contentPart.PartDefinition.Name));
|
||||
throw new InvalidOperationException(string.Format("Could set setting {0} for part {1} because it was not found.", attributeName, sitePart.PartDefinition.Name));
|
||||
}
|
||||
|
||||
var propertyType = property.PropertyType;
|
||||
if (propertyType == typeof(string)) {
|
||||
property.SetValue(contentPart, attributeValue, null);
|
||||
property.SetValue(sitePart, attributeValue, null);
|
||||
}
|
||||
else if (propertyType == typeof(bool)) {
|
||||
property.SetValue(contentPart, Boolean.Parse(attributeValue), null);
|
||||
property.SetValue(sitePart, Boolean.Parse(attributeValue), null);
|
||||
}
|
||||
else if (propertyType == typeof(int)) {
|
||||
property.SetValue(contentPart, Int32.Parse(attributeValue), null);
|
||||
}
|
||||
else {
|
||||
throw new InvalidOperationException(string.Format("Could set setting {0} for part {1} because its type is not supported. Settings should be integer,boolean or string.", attributeName, contentPart.PartDefinition.Name));
|
||||
property.SetValue(sitePart, Int32.Parse(attributeValue), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.Indexing;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Search.Models;
|
||||
@@ -61,5 +63,19 @@ namespace Orchard.Search.Drivers {
|
||||
return shapeHelper.EditorTemplate(TemplateName: "Parts/Search.SiteSettings", Model: model, Prefix: Prefix);
|
||||
}).OnGroup("search");
|
||||
}
|
||||
|
||||
protected override void Exporting(SearchSettingsPart part, ExportContentContext context) {
|
||||
context.Element(part.PartDefinition.Name).Add(new XAttribute("SearchedFields", string.Join(",", part.SearchedFields)));
|
||||
}
|
||||
|
||||
protected override void Importing(SearchSettingsPart part, ImportContentContext context) {
|
||||
var xElement = context.Data.Element(part.PartDefinition.Name);
|
||||
if (xElement == null) return;
|
||||
|
||||
var searchedFields = xElement.Attribute("SearchedFields");
|
||||
searchedFields.Remove();
|
||||
|
||||
part.SearchedFields = searchedFields.Value.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
}
|
||||
}
|
@@ -60,6 +60,7 @@
|
||||
<HintPath>..\..\..\..\lib\aspnetmvc\System.Web.Mvc.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.FieldStorage.InfosetStorage;
|
||||
|
||||
@@ -45,11 +46,13 @@ namespace Orchard.SecureSocketsLayer.Models {
|
||||
set { this.As<InfosetPart>().Set<SslSettingsPart>("CustomEnabled", value.ToString()); }
|
||||
}
|
||||
|
||||
[Required]
|
||||
public string SecureHostName {
|
||||
get { return this.As<InfosetPart>().Get<SslSettingsPart>("SecureHostName"); }
|
||||
set { this.As<InfosetPart>().Set<SslSettingsPart>("SecureHostName", value); }
|
||||
}
|
||||
|
||||
[Required]
|
||||
public string InsecureHostName {
|
||||
get { return this.As<InfosetPart>().Get<SslSettingsPart>("InsecureHostName"); }
|
||||
set { this.As<InfosetPart>().Set<SslSettingsPart>("InsecureHostName", value); }
|
||||
|
@@ -99,6 +99,10 @@ namespace Orchard.SecureSocketsLayer.Services {
|
||||
var urlHelper = new UrlHelper(requestContext);
|
||||
var url = urlHelper.Action(actionName, controllerName, requestContext.RouteData);
|
||||
|
||||
if (String.IsNullOrWhiteSpace(url)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return IsRequestProtected(
|
||||
url, requestContext.HttpContext.Request.ApplicationPath, settings);
|
||||
}
|
||||
|
@@ -8,6 +8,16 @@
|
||||
@Html.ValidationMessage("Enabled", "*")
|
||||
</div>
|
||||
<div data-controllerid="@Html.FieldIdFor(m => m.Enabled)">
|
||||
<div>
|
||||
<label for="@Html.FieldIdFor(m => m.SecureHostName)">@T("Secure Host Name")</label>
|
||||
@Html.TextBoxFor(m => m.SecureHostName, new { @class = "textMedium" })
|
||||
<span class="hint">@T("(Mandatory) The host name secured traffic should be redirected to (e.g. localhost:44300, secure.mydomain.com). Don't include the protocol or anything else than the host name. A port can be specified after a colon if necessary (e.g. secure.127-0-0-1.org.uk:4333).")</span>
|
||||
</div>
|
||||
<div>
|
||||
<label for="@Html.FieldIdFor(m => m.InsecureHostName)">@T("Insecure Host Name")</label>
|
||||
@Html.TextBoxFor(m => m.InsecureHostName, new { @class = "textMedium" })
|
||||
<span class="hint">@T("(Mandatory) The host name non-secured traffic should be redirected to (e.g. localhost:30321, mydomain.com). Don't include the protocol or anything else than the host name. A port can be specified after a colon if necessary (e.g. dev.127-0-0-1.org.uk:4333).")</span>
|
||||
</div>
|
||||
<div>
|
||||
@Html.EditorFor(m => m.SecureEverything)
|
||||
<label for="@Html.FieldIdFor(m => m.SecureEverything)" class="forcheckbox">@T("Force SSL on all pages")</label>
|
||||
@@ -29,16 +39,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label for="@Html.FieldIdFor(m => m.SecureHostName)">@T("Secure Host Name")</label>
|
||||
@Html.TextBoxFor(m => m.SecureHostName, new { @class = "textMedium" })
|
||||
<span class="hint">@T("Provide the host name secure traffic should be redirected to (e.g. secure.mydomain.com). Don't include the protocol or anything else than the host name. A port can be specified after a colon if necessary (e.g. secure.127-0-0-1.org.uk:4333).")</span>
|
||||
</div>
|
||||
<div>
|
||||
<label for="@Html.FieldIdFor(m => m.InsecureHostName)">@T("Insecure Host Name")</label>
|
||||
@Html.TextBoxFor(m => m.InsecureHostName, new { @class = "textMedium" })
|
||||
<span class="hint">@T("Provide the host name non-secured traffic should be redirected to (e.g. mydomain.com). Don't include the protocol or anything else than the host name. A port can be specified after a colon if necessary (e.g. dev.127-0-0-1.org.uk:4333).")</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
@@ -59,7 +59,8 @@
|
||||
site setting set baseurl
|
||||
theme activate "The Theme Machine"
|
||||
menu create /MenuName:"Main Menu"
|
||||
blog create /Title:"Blog" /Homepage:true /Description:"This is your Orchard Blog." /MenuText:"Home" /MenuName:"Main Menu"
|
||||
blog create /Title:"Blog" /Homepage:true /Description:"This is your Orchard Blog."
|
||||
menuitem create /MenuPosition:"0" /MenuText:"Home" /Url:"~/" /MenuName:"Main Menu"
|
||||
widget create MenuWidget /Title:"Main Menu" /RenderTitle:false /Zone:"Navigation" /Position:"1" /Layer:"Default" /Identity:"MenuWidget1" /MenuName:"Main Menu"
|
||||
</Command>
|
||||
</Orchard>
|
||||
|
@@ -26,6 +26,8 @@
|
||||
<Migration features="*" />
|
||||
|
||||
<Command>
|
||||
page create /Slug:"welcome-to-orchard" /Title:"Welcome to Orchard!" /Path:"welcome-to-orchard" /Homepage:true /Publish:true /Text:"Welcome To Orchard!" /MenuText:"Home" /MenuName:"Main Menu"
|
||||
menu create /MenuName:"Main Menu"
|
||||
page create /Slug:"welcome-to-orchard" /Title:"Welcome to Orchard!" /Path:"welcome-to-orchard" /Homepage:true /Publish:true /Text:"Welcome To Orchard!"
|
||||
menuitem create /MenuPosition:"0" /MenuText:"Home" /Url:"~/" /MenuName:"Main Menu"
|
||||
</Command>
|
||||
</Orchard>
|
||||
|
@@ -53,7 +53,8 @@
|
||||
widget create HtmlWidget /Title:"Third Leader Aside" /Zone:"TripelThird" /Position:"5" /Layer:"TheHomepage" /Identity:"SetupHtmlWidget3" /UseLoremIpsumText:true
|
||||
site setting set baseurl
|
||||
menu create /MenuName:"Main Menu"
|
||||
page create /Slug:"welcome-to-orchard" /Title:"Welcome to Orchard!" /Path:"welcome-to-orchard" /Homepage:true /Publish:true /UseWelcomeText:true /MenuText:"Home" /MenuName:"Main Menu"
|
||||
page create /Slug:"welcome-to-orchard" /Title:"Welcome to Orchard!" /Path:"welcome-to-orchard" /Homepage:true /Publish:true /UseWelcomeText:true
|
||||
menuitem create /MenuPosition:"0" /MenuText:"Home" /Url:"~/" /MenuName:"Main Menu"
|
||||
widget create MenuWidget /Title:"Main Menu" /RenderTitle:false /Zone:"Navigation" /Position:"1" /Layer:"Default" /Identity:"MenuWidget1" /MenuName:"Main Menu"
|
||||
theme activate "The Theme Machine"
|
||||
</Command>
|
||||
|
@@ -167,6 +167,9 @@ namespace Orchard.Taxonomies.Controllers {
|
||||
var term = _taxonomyService.NewTerm(taxonomy);
|
||||
term.Container = parentTerm == null ? taxonomy.ContentItem : parentTerm.ContentItem;
|
||||
|
||||
// Create content item before updating so attached fields save correctly
|
||||
Services.ContentManager.Create(term, VersionOptions.Draft);
|
||||
|
||||
var model = Services.ContentManager.UpdateEditor(term, this);
|
||||
|
||||
if (!ModelState.IsValid) {
|
||||
@@ -175,7 +178,7 @@ namespace Orchard.Taxonomies.Controllers {
|
||||
}
|
||||
|
||||
_taxonomyService.ProcessPath(term);
|
||||
Services.ContentManager.Create(term, VersionOptions.Published);
|
||||
Services.ContentManager.Publish(term.ContentItem);
|
||||
Services.Notifier.Information(T("The {0} term has been created.", term.Name));
|
||||
|
||||
return RedirectToAction("Index", "TermAdmin", new { taxonomyId });
|
||||
|
@@ -32,7 +32,10 @@ namespace Orchard.Taxonomies.Tokens {
|
||||
context.For<TaxonomyField>("TaxonomyField")
|
||||
.Token("Terms", field => String.Join(", ", field.Terms.Select(t => t.Name).ToArray()))
|
||||
.Token(
|
||||
token => token.StartsWith("Terms:", StringComparison.OrdinalIgnoreCase) ? token.Substring("Terms:".Length) : null,
|
||||
token => {
|
||||
var index = 0;
|
||||
return (token.StartsWith("Terms:", StringComparison.OrdinalIgnoreCase) && int.TryParse(token.Substring("Terms:".Length), out index)) ? index.ToString() : null;
|
||||
},
|
||||
(token, t) => {
|
||||
var index = Convert.ToInt32(token);
|
||||
return index + 1 > t.Terms.Count() ? null : t.Terms.ElementAt(index).Name;
|
||||
|
@@ -30,6 +30,11 @@ namespace Orchard.Users.Commands {
|
||||
[CommandHelp("user create /UserName:<username> /Password:<password> /Email:<email>\r\n\t" + "Creates a new User")]
|
||||
[OrchardSwitches("UserName,Password,Email")]
|
||||
public void Create() {
|
||||
if (string.IsNullOrWhiteSpace(UserName)) {
|
||||
Context.Output.WriteLine(T("Username cannot be empty."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_userService.VerifyUserUnicity(UserName, Email)) {
|
||||
Context.Output.WriteLine(T("User with that username and/or email already exists."));
|
||||
return;
|
||||
|
@@ -121,7 +121,7 @@ namespace Orchard.Users.Controllers {
|
||||
[HttpPost]
|
||||
[AlwaysAccessible]
|
||||
[ValidateInput(false)]
|
||||
public ActionResult Register(string userName, string email, string password, string confirmPassword) {
|
||||
public ActionResult Register(string userName, string email, string password, string confirmPassword, string returnUrl = null) {
|
||||
// ensure users can register
|
||||
var registrationSettings = _orchardServices.WorkContext.CurrentSite.As<RegistrationSettingsPart>();
|
||||
if ( !registrationSettings.UsersCanRegister ) {
|
||||
@@ -153,7 +153,7 @@ namespace Orchard.Users.Controllers {
|
||||
}
|
||||
|
||||
_authenticationService.SignIn(user, false /* createPersistentCookie */);
|
||||
return Redirect("~/");
|
||||
return this.RedirectLocal(returnUrl);
|
||||
}
|
||||
|
||||
ModelState.AddModelError("_FORM", T(ErrorCodeToString(/*createStatus*/MembershipCreateStatus.ProviderError)));
|
||||
|
@@ -8,7 +8,7 @@
|
||||
<h1 class="page-title">@Html.TitleForPage((string)Model.Title)</h1>
|
||||
<p>
|
||||
@T("Please enter your username and password.")
|
||||
@if(userCanRegister) { @Html.ActionLink(T("Register").Text, "Register") @T(" if you don't have an account.") }
|
||||
@if(userCanRegister) { @Html.ActionLink(T("Register").Text, "Register", new { ReturnUrl = Request.QueryString["ReturnUrl"] }) @T(" if you don't have an account.") }
|
||||
@if(enableLostPassword) { <text> </text> @Html.ActionLink(T("Lost your Password?").Text, "RequestLostPassword") }
|
||||
</p>
|
||||
@Html.ValidationSummary(T("Login was unsuccessful. Please correct the errors and try again.").ToString())
|
||||
|
@@ -2,7 +2,7 @@
|
||||
<p>@T("Use the form below to create a new account.")</p>
|
||||
<p>@T("Passwords are required to be a minimum of {0} characters in length.", ViewData["PasswordLength"])</p>
|
||||
@Html.ValidationSummary(T("Account creation was unsuccessful. Please correct the errors and try again.").ToString())
|
||||
@using (Html.BeginFormAntiForgeryPost()) {
|
||||
@using (Html.BeginFormAntiForgeryPost(Url.Action("Register", new { ReturnUrl = Request.QueryString["ReturnUrl"] }))) {
|
||||
<fieldset>
|
||||
<legend>@T("Account Information")</legend>
|
||||
<div>
|
||||
|
@@ -2,7 +2,7 @@
|
||||
@using Orchard.Widgets.Models;
|
||||
@{
|
||||
Style.Require("WidgetsAdmin");
|
||||
Script.Require("Switchable");
|
||||
Script.Require("Switchable").AtFoot();
|
||||
Style.Require("Switchable");
|
||||
IEnumerable<LayerPart> layers = Model.Layers;
|
||||
var returnUrl = Request.RawUrl;
|
||||
|
@@ -7,7 +7,7 @@
|
||||
Style.Require("WorkflowsAdmin");
|
||||
Style.Require("WorkflowsActivities");
|
||||
Style.Require("jQueryUI_Orchard");
|
||||
Script.Require("jsPlumb");
|
||||
Script.Require("jsPlumb").AtFoot();
|
||||
Script.Include("orchard-workflows-serialize.js").AtFoot();
|
||||
Script.Include("orchard-workflows.js").AtFoot();
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
@{
|
||||
Layout.Title = @T("Edit Activity");
|
||||
Script.Include("orchard-workflows-serialize.js");
|
||||
Script.Include("orchard-workflows-serialize.js").AtFoot();
|
||||
}
|
||||
|
||||
@Html.ValidationSummary()
|
||||
|
@@ -72,7 +72,7 @@
|
||||
});
|
||||
|
||||
$(".check-all").change(function () {
|
||||
$(this).parents("table.items").find(":checkbox").prop('checked', $(this).prop("checked"));
|
||||
$(this).parents("table.items").find(":checkbox:not(:disabled)").prop('checked', $(this).prop("checked"));
|
||||
});
|
||||
})(jQuery);
|
||||
|
||||
|
@@ -11,9 +11,9 @@
|
||||
Style.Include("ie.css").UseCondition("gte IE 9").SetAttribute("media", "screen, projection");
|
||||
Style.Include("ie8.css").UseCondition("IE 8").SetAttribute("media", "screen, projection");
|
||||
Style.Include("ie7.css").UseCondition("lte IE 7").SetAttribute("media", "screen, projection");
|
||||
Script.Require("jQuery");
|
||||
Script.Require("ShapesBase");
|
||||
Script.Include("admin.js");
|
||||
Script.Require("jQuery").AtFoot();
|
||||
Script.Require("ShapesBase").AtFoot();
|
||||
Script.Include("admin.js").AtFoot();
|
||||
|
||||
/* Some useful shortcuts or settings
|
||||
***************************************************************/
|
||||
|
@@ -1,7 +1,7 @@
|
||||
@using Orchard.Utility.Extensions;
|
||||
@{
|
||||
Script.Require("jQuery");
|
||||
Script.Include("admin.js");
|
||||
Script.Include("admin.js").AtFoot();
|
||||
IEnumerable<dynamic> firstLevelMenuItems = Model;
|
||||
|
||||
if (Model.ImageSets != null) {
|
||||
|
@@ -52,17 +52,17 @@ namespace Orchard.ContentManagement {
|
||||
return tuple == null ? null : tuple.Item2;
|
||||
}
|
||||
|
||||
internal IAlias BindCriteriaByPath(IAlias alias, string path) {
|
||||
return BindCriteriaByAlias(alias, path, PathToAlias(path));
|
||||
internal IAlias BindCriteriaByPath(IAlias alias, string path, string type = null, Action<IHqlExpressionFactory> withPredicate = null) {
|
||||
return BindCriteriaByAlias(alias, path, PathToAlias(path), type, withPredicate);
|
||||
}
|
||||
|
||||
internal IAlias BindCriteriaByAlias(IAlias alias, string path, string aliasName) {
|
||||
internal IAlias BindCriteriaByAlias(IAlias alias, string path, string aliasName, string type = null, Action<IHqlExpressionFactory> withPredicate = null) {
|
||||
// is this Join already existing (based on aliasName)
|
||||
|
||||
Join join = BindNamedAlias(aliasName);
|
||||
|
||||
if (join == null) {
|
||||
join = new Join(path, aliasName);
|
||||
join = new Join(path, aliasName, type, withPredicate);
|
||||
_joins.Add(new Tuple<IAlias, Join>(alias, join));
|
||||
}
|
||||
|
||||
@@ -88,19 +88,19 @@ namespace Orchard.ContentManagement {
|
||||
return _from;
|
||||
}
|
||||
|
||||
internal IAlias BindPartCriteria<TRecord>() where TRecord : ContentPartRecord {
|
||||
return BindPartCriteria(typeof(TRecord));
|
||||
internal IAlias BindPartCriteria<TRecord>(string type = null, Action<IHqlExpressionFactory> withPredicate = null) where TRecord : ContentPartRecord {
|
||||
return BindPartCriteria(typeof(TRecord), type, withPredicate);
|
||||
}
|
||||
|
||||
internal IAlias BindPartCriteria(Type contentPartRecordType) {
|
||||
internal IAlias BindPartCriteria(Type contentPartRecordType, string type = null, Action<IHqlExpressionFactory> withPredicate = null) {
|
||||
if (!contentPartRecordType.IsSubclassOf(typeof(ContentPartRecord))) {
|
||||
throw new ArgumentException("The type must inherit from ContentPartRecord", "contentPartRecordType");
|
||||
}
|
||||
|
||||
if (contentPartRecordType.IsSubclassOf(typeof(ContentPartVersionRecord))) {
|
||||
return BindCriteriaByPath(BindItemVersionCriteria(), contentPartRecordType.Name);
|
||||
return BindCriteriaByPath(BindItemVersionCriteria(), contentPartRecordType.Name, type, withPredicate);
|
||||
}
|
||||
return BindCriteriaByPath(BindItemCriteria(), contentPartRecordType.Name);
|
||||
return BindCriteriaByPath(BindItemCriteria(), contentPartRecordType.Name, type, withPredicate);
|
||||
}
|
||||
|
||||
internal void Where(IAlias alias, Action<IHqlExpressionFactory> predicate) {
|
||||
@@ -246,7 +246,16 @@ namespace Orchard.ContentManagement {
|
||||
sb.Append("from ").Append(_from.TableName).Append(" as ").Append(_from.Name).AppendLine();
|
||||
|
||||
foreach (var join in _joins) {
|
||||
sb.Append(join.Item2.Type).Append(" ").Append(join.Item1.Name + "." + join.Item2.TableName).Append(" as ").Append(join.Item2.Name).AppendLine();
|
||||
sb.Append(join.Item2.Type + " " +
|
||||
join.Item1.Name + "." + join.Item2.TableName +
|
||||
" as " + join.Item2.Name);
|
||||
if (join.Item2.WithPredicate != null) {
|
||||
var predicate = join.Item2.WithPredicate;
|
||||
var expressionFactory = new DefaultHqlExpressionFactory();
|
||||
predicate(expressionFactory);
|
||||
sb.Append(" with " + expressionFactory.Criterion.ToHql(join.Item2));
|
||||
}
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
// generating where clause
|
||||
@@ -378,6 +387,7 @@ namespace Orchard.ContentManagement {
|
||||
public interface IJoin : IAlias {
|
||||
string TableName { get; set; }
|
||||
string Type { get; set; }
|
||||
Action<IHqlExpressionFactory> WithPredicate { get; set; }
|
||||
}
|
||||
|
||||
public class Sort {
|
||||
@@ -396,20 +406,26 @@ namespace Orchard.ContentManagement {
|
||||
public class Join : Alias, IJoin {
|
||||
|
||||
public Join(string tableName, string alias)
|
||||
: this(tableName, alias, "join") {}
|
||||
: this(tableName, alias, "join", null) {}
|
||||
|
||||
public Join(string tableName, string alias, string type)
|
||||
: this(tableName, alias, type, null) {
|
||||
}
|
||||
|
||||
public Join(string tableName, string alias, string type, Action<IHqlExpressionFactory> withPredicate)
|
||||
: base(alias) {
|
||||
if (String.IsNullOrEmpty(tableName)) {
|
||||
throw new ArgumentException("Table Name can't be empty");
|
||||
}
|
||||
|
||||
TableName = tableName;
|
||||
Type = type;
|
||||
Type = type ?? "join";
|
||||
WithPredicate = withPredicate;
|
||||
}
|
||||
|
||||
public string TableName { get; set; }
|
||||
public string Type { get; set; }
|
||||
public Action<IHqlExpressionFactory> WithPredicate { get; set; }
|
||||
}
|
||||
|
||||
public class DefaultHqlSortFactory : IHqlSortFactory
|
||||
@@ -442,17 +458,17 @@ namespace Orchard.ContentManagement {
|
||||
Current = _query.BindItemCriteria();
|
||||
}
|
||||
|
||||
public IAliasFactory ContentPartRecord<TRecord>() where TRecord : ContentPartRecord {
|
||||
Current = _query.BindPartCriteria<TRecord>();
|
||||
public IAliasFactory ContentPartRecord<TRecord>(string type = null, Action<IHqlExpressionFactory> withPredicate = null) where TRecord : ContentPartRecord {
|
||||
Current = _query.BindPartCriteria<TRecord>(type, withPredicate);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAliasFactory ContentPartRecord(Type contentPartRecord) {
|
||||
public IAliasFactory ContentPartRecord(Type contentPartRecord, string type = null, Action<IHqlExpressionFactory> withPredicate = null) {
|
||||
if(!contentPartRecord.IsSubclassOf(typeof(ContentPartRecord))) {
|
||||
throw new ArgumentException("Type must inherit from ContentPartRecord", "contentPartRecord");
|
||||
}
|
||||
|
||||
Current = _query.BindPartCriteria(contentPartRecord);
|
||||
Current = _query.BindPartCriteria(contentPartRecord, type, withPredicate);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@@ -30,6 +30,15 @@ namespace Orchard.ContentManagement.Drivers {
|
||||
if (string.IsNullOrEmpty(placement.Location) || placement.Location == "-")
|
||||
return;
|
||||
|
||||
// parse group placement
|
||||
var group = placement.GetGroup();
|
||||
if (!String.IsNullOrEmpty(group)) {
|
||||
_groupId = group;
|
||||
}
|
||||
|
||||
if (!string.Equals(context.GroupId ?? "", _groupId ?? "", StringComparison.OrdinalIgnoreCase))
|
||||
return;
|
||||
|
||||
dynamic parentShape = context.Shape;
|
||||
context.ContentPart = ContentPart;
|
||||
|
||||
@@ -62,15 +71,6 @@ namespace Orchard.ContentManagement.Drivers {
|
||||
newShapeMetadata.Wrappers.Clear();
|
||||
}
|
||||
|
||||
// parse group placement
|
||||
var group = placement.GetGroup();
|
||||
if (!String.IsNullOrEmpty(group)) {
|
||||
_groupId = group;
|
||||
}
|
||||
|
||||
if (!string.Equals(context.GroupId ?? "", _groupId ?? "", StringComparison.OrdinalIgnoreCase))
|
||||
return;
|
||||
|
||||
foreach (var alternate in placement.Alternates) {
|
||||
newShapeMetadata.Alternates.Add(alternate);
|
||||
}
|
||||
|
@@ -133,13 +133,18 @@ namespace Orchard.ContentManagement {
|
||||
public interface IAliasFactory {
|
||||
/// <summary>
|
||||
/// Creates a join on a content part record or returns it if it already exists.
|
||||
/// <param name="type">The type of join, e.g. "left outer join"</param>
|
||||
/// <param name="withPredicate">An expression for an additional constraint on the join</param>
|
||||
/// </summary>
|
||||
IAliasFactory ContentPartRecord<TRecord>() where TRecord : ContentPartRecord;
|
||||
IAliasFactory ContentPartRecord<TRecord>(string type = null, Action<IHqlExpressionFactory> withPredicate = null) where TRecord : ContentPartRecord;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a join on a content part record or returns it if it already exists.
|
||||
/// <param name="contentPartRecord">The type of the part to join</param>
|
||||
/// <param name="type">The type of join, e.g. "left outer join"</param>
|
||||
/// <param name="withPredicate">An expression for an additional constraint on the join</param>
|
||||
/// </summary>
|
||||
IAliasFactory ContentPartRecord(Type contentPartRecord);
|
||||
IAliasFactory ContentPartRecord(Type contentPartRecord, string type = null, Action<IHqlExpressionFactory> withPredicate = null);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a join based on a property, or returns it if it already exists.
|
||||
|
@@ -2,12 +2,32 @@
|
||||
using Orchard.Reports.Services;
|
||||
|
||||
public static class ReportExtentions {
|
||||
/// <summary>
|
||||
/// Adds a new report entry of type information to a report that was previously registered.
|
||||
/// </summary>
|
||||
/// <seealso cref="Register()"/>
|
||||
/// <param name="reportKey">Key, i.e. technical name of the report. Should be the same as the one used when registering the report.</param>
|
||||
/// <param name="message">The message to include in the entry.</param>
|
||||
public static void Information(this IReportsCoordinator reportCoordinator, string reportKey, string message) {
|
||||
reportCoordinator.Add(reportKey, ReportEntryType.Information, message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new report entry of type warning to a report that was previously registered.
|
||||
/// </summary>
|
||||
/// <seealso cref="Register()"/>
|
||||
/// <param name="reportKey">Key, i.e. technical name of the report. Should be the same as the one used when registering the report.</param>
|
||||
/// <param name="message">The message to include in the entry.</param>
|
||||
public static void Warning(this IReportsCoordinator reportCoordinator, string reportKey, string message) {
|
||||
reportCoordinator.Add(reportKey, ReportEntryType.Warning, message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new report entry of type error to a report that was previously registered.
|
||||
/// </summary>
|
||||
/// <seealso cref="Register()"/>
|
||||
/// <param name="reportKey">Key, i.e. technical name of the report. Should be the same as the one used when registering the report.</param>
|
||||
/// <param name="message">The message to include in the entry.</param>
|
||||
public static void Error(this IReportsCoordinator reportCoordinator, string reportKey, string message) {
|
||||
reportCoordinator.Add(reportKey, ReportEntryType.Error, message);
|
||||
}
|
||||
|
@@ -1,6 +1,30 @@
|
||||
namespace Orchard.Reports.Services {
|
||||
/// <summary>
|
||||
/// Exposes a simplified interface for creating reports. Reports provide user-accessible log-like functionality.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <see cref="Orchard.Reports.Services.IReportsManager"/> can be used too to create reports directly.
|
||||
/// </remarks>
|
||||
public interface IReportsCoordinator : IDependency {
|
||||
/// <summary>
|
||||
/// Adds a new report entry to a report that was previously registered.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Entries can be only added to a report that was previously registered through Register().
|
||||
/// </remarks>
|
||||
/// <seealso cref="Register()"/>
|
||||
/// <param name="reportKey">Key, i.e. technical name of the report. Should be the same as the one used when registering the report.</param>
|
||||
/// <param name="type">Type of the entry.</param>
|
||||
/// <param name="message">The message to include in the entry.</param>
|
||||
void Add(string reportKey, ReportEntryType type, string message);
|
||||
|
||||
/// <summary>
|
||||
/// Registers a new report so entries can be added to it.
|
||||
/// </summary>
|
||||
/// <param name="reportKey">Key, i.e. technical name of the report.</param>
|
||||
/// <param name="activityName">Name of the activity the report is about (e.g. "Upgrade").</param>
|
||||
/// <param name="title">A title better describing what the report is about (e.g. "Migrating routes of Pages, Blog Posts").</param>
|
||||
/// <returns>The report's numerical ID.</returns>
|
||||
int Register(string reportKey, string activityName, string title);
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Orchard.Reports.Services {
|
||||
/// <summary>
|
||||
/// Service for handling reports. Reports provide user-accessible log-like functionality.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// You can use <see cref="Orchard.Reports.Services.IReportsCoordinator"/> to create reports through a simplified interface.
|
||||
/// </remarks>
|
||||
public interface IReportsManager : ISingletonDependency {
|
||||
void Add(int reportId, ReportEntryType type, string message);
|
||||
int CreateReport(string title, string activityName);
|
||||
|
@@ -1,6 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Orchard.Reports.Services {
|
||||
/// <summary>
|
||||
/// Defines a service that can be used to persist reports.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Implementations of this interface are commonly used from <see cref="Orchard.Reports.Services.IReportsManager"/> implementations.
|
||||
/// </remarks>
|
||||
public interface IReportsPersister : IDependency {
|
||||
IEnumerable<Report> Fetch();
|
||||
void Save(IEnumerable<Report> reports);
|
||||
|
@@ -5,6 +5,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Orchard.Localization;
|
||||
using System.Web;
|
||||
|
||||
namespace Orchard.Utility.Extensions {
|
||||
public static class StringExtensions {
|
||||
@@ -89,7 +90,7 @@ namespace Orchard.Utility.Extensions {
|
||||
: new LocalizedString(text);
|
||||
}
|
||||
|
||||
public static string RemoveTags(this string html) {
|
||||
public static string RemoveTags(this string html, bool htmlDecode = false) {
|
||||
if (String.IsNullOrEmpty(html)) {
|
||||
return String.Empty;
|
||||
}
|
||||
@@ -115,7 +116,13 @@ namespace Orchard.Utility.Extensions {
|
||||
}
|
||||
}
|
||||
|
||||
return new string(result, 0, cursor);
|
||||
var stringResult = new string(result, 0, cursor);
|
||||
|
||||
if (htmlDecode) {
|
||||
stringResult = HttpUtility.HtmlDecode(stringResult);
|
||||
}
|
||||
|
||||
return stringResult;
|
||||
}
|
||||
|
||||
// not accounting for only \r (e.g. Apple OS 9 carriage return only new lines)
|
||||
@@ -167,9 +174,7 @@ namespace Orchard.Utility.Extensions {
|
||||
|
||||
name = RemoveDiacritics(name);
|
||||
name = name.Strip(c =>
|
||||
c != '_'
|
||||
&& c != '-'
|
||||
&& !c.IsLetter()
|
||||
!c.IsLetter()
|
||||
&& !Char.IsDigit(c)
|
||||
);
|
||||
|
||||
|
Reference in New Issue
Block a user