mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-25 19:17:13 +08:00
Merge branch '1.10.x' into 1.10.x-to-dev
# Conflicts: # src/Orchard.Web/Core/Contents/Controllers/AdminController.cs # src/Orchard.Web/Core/Contents/Drivers/ContentsDriver.cs # src/Orchard.Web/Core/Contents/Placement.info # src/Orchard.Web/Modules/Orchard.Fields/Orchard.Fields.csproj # src/Orchard.Web/Themes/TheAdmin/Styles/site.css # src/Orchard/Orchard.Framework.csproj
This commit is contained in:
@@ -362,6 +362,32 @@ namespace Orchard.Core.Contents.Controllers {
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This action is specific to the submit button of the edit form.
|
||||
/// Unpublish logic is the same of the Unpublish action, which is called by the content list.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="returnUrl"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost, ActionName("Edit")]
|
||||
[Mvc.FormValueRequired("submit.Unpublish")]
|
||||
public ActionResult EditUnpublishPOST(int id, string returnUrl) {
|
||||
return Unpublish(id, returnUrl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This action is specific to the submit button of the edit form.
|
||||
/// Delete logic is the same of the Remove action, which is called by the content list.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="returnUrl"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost, ActionName("Edit")]
|
||||
[Mvc.FormValueRequired("submit.Delete")]
|
||||
public ActionResult EditDeletePOST(int id, string returnUrl) {
|
||||
return Remove(id, returnUrl);
|
||||
}
|
||||
|
||||
private ActionResult EditPOST(int id, string returnUrl, Func<ContentItem, bool> conditionallyPublish) {
|
||||
var contentItem = _contentManager.Get(id, VersionOptions.DraftRequired);
|
||||
|
||||
|
||||
@@ -17,12 +17,17 @@ namespace Orchard.Core.Contents.Drivers {
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(ContentPart part, dynamic shapeHelper) {
|
||||
var results = new List<DriverResult>();
|
||||
var results = new List<DriverResult> { ContentShape("Content_SaveButton", saveButton => saveButton) };
|
||||
|
||||
if (part.TypeDefinition.Settings.GetModel<ContentTypeSettings>().Draftable)
|
||||
results.Add(ContentShape("Content_SaveButton", saveButton => saveButton));
|
||||
if (part.TypeDefinition.Settings.GetModel<ContentTypeSettings>().Draftable) {
|
||||
results.Add(ContentShape("Content_PublishButton", publishButton => publishButton));
|
||||
results.Add(ContentShape("Content_UnpublishButton", unpublishButton => unpublishButton));
|
||||
}
|
||||
|
||||
results.Add(ContentShape("Content_PublishButton", publishButton => publishButton));
|
||||
if (part.Id > 0) {
|
||||
results.Add(ContentShape("Content_DeleteButton", deleteButton => deleteButton));
|
||||
}
|
||||
|
||||
results.Add(ContentShape("Content_CancelButton", cancelButton => cancelButton));
|
||||
|
||||
return Combined(results.ToArray());
|
||||
|
||||
@@ -7,8 +7,10 @@
|
||||
-->
|
||||
<!-- edit "shape" -->
|
||||
<Place Content_SaveButton="Sidebar:23"/>
|
||||
<Place Content_PublishButton="Sidebar:24"/>
|
||||
<Place Content_CancelButton="Sidebar:26"/>
|
||||
<Place Content_PublishButton="Sidebar:24"/>
|
||||
<Place Content_UnpublishButton="Sidebar:25"/>
|
||||
<Place Content_DeleteButton="Sidebar:26"/>
|
||||
<Place Content_CancelButton="Sidebar:27"/>
|
||||
<Match DisplayType="Detail">
|
||||
<Place Parts_Contents_Publish="Content:5"/>
|
||||
</Match>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
@using Orchard.ContentManagement;
|
||||
@using Orchard.Core.Contents;
|
||||
|
||||
@if (Authorizer.Authorize(Permissions.DeleteContent, (IContent)Model.ContentItem)) {
|
||||
<fieldset class="delete-button">
|
||||
<button type="submit" name="submit.Delete" value="submit.Delete" itemprop="RemoveUrl">@T("Delete")</button>
|
||||
</fieldset>
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
@using Orchard.ContentManagement;
|
||||
@using Orchard.Core.Contents;
|
||||
|
||||
@{
|
||||
var contentItem = Model.ContentItem as IContent;
|
||||
}
|
||||
|
||||
@if (Authorizer.Authorize(Permissions.PublishContent, contentItem) && contentItem.IsPublished()) {
|
||||
<fieldset class="unpublish-button">
|
||||
<button type="submit" name="submit.Unpublish" value="submit.Unpublish">@T("Unpublish")</button>
|
||||
</fieldset>
|
||||
}
|
||||
@@ -629,12 +629,16 @@
|
||||
<Content Include="Contents\Views\Parts.Contents.Clone.SummaryAdmin.cshtml" />
|
||||
<Content Include="Navigation\Views\Admin\Edit.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Contents\Views\Content.UnpublishButton.cshtml" />
|
||||
<Content Include="Contents\Views\Content.DeleteButton.cshtml" />
|
||||
<None Include="packages.config" />
|
||||
<Content Include="Title\Views\DefinitionTemplates\TitlePartSettings.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Containers\Styles\Web.config">
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
<None Include="packages.config" />
|
||||
<Content Include="Title\Views\DefinitionTemplates\TitlePartSettings.cshtml" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.Blogs.Extensions;
|
||||
using Orchard.Blogs.Models;
|
||||
@@ -138,6 +137,12 @@ namespace Orchard.Blogs.Controllers {
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("Edit")]
|
||||
[Mvc.FormValueRequired("submit.Delete")]
|
||||
public ActionResult EditDeletePOST(int blogId, int postId, string returnUrl) {
|
||||
return Delete(blogId, postId);
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("Edit")]
|
||||
[FormValueRequired("submit.Publish")]
|
||||
public ActionResult EditAndPublishPOST(int blogId, int postId, string returnUrl) {
|
||||
@@ -156,6 +161,12 @@ namespace Orchard.Blogs.Controllers {
|
||||
return EditPOST(blogId, postId, returnUrl, contentItem => Services.ContentManager.Publish(contentItem));
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("Edit")]
|
||||
[Mvc.FormValueRequired("submit.Unpublish")]
|
||||
public ActionResult EditUnpublishPOST(int blogId, int postId, string returnUrl) {
|
||||
return Unpublish(blogId, postId);
|
||||
}
|
||||
|
||||
public ActionResult EditPOST(int blogId, int postId, string returnUrl, Action<ContentItem> conditionallyPublish) {
|
||||
var blog = _blogService.Get(blogId, VersionOptions.Latest);
|
||||
if (blog == null)
|
||||
|
||||
@@ -8,4 +8,8 @@ namespace Orchard.Caching.Services {
|
||||
void Remove(string key);
|
||||
void Clear();
|
||||
}
|
||||
|
||||
public interface ICacheStorageProviderWithKeyPrefix : ICacheStorageProvider {
|
||||
void Clear(string key);
|
||||
}
|
||||
}
|
||||
@@ -4,41 +4,46 @@ using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.Fields.Fields;
|
||||
using Orchard.Fields.Settings;
|
||||
using Orchard.Localization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Orchard.Fields.Drivers {
|
||||
public class EnumerationFieldDriver : ContentFieldDriver<EnumerationField> {
|
||||
public IOrchardServices Services { get; set; }
|
||||
|
||||
private const string TemplateName = "Fields/Enumeration.Edit";
|
||||
|
||||
public EnumerationFieldDriver(IOrchardServices services) {
|
||||
Services = services;
|
||||
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
|
||||
private static string GetPrefix(ContentField field, ContentPart part) =>
|
||||
part.PartDefinition.Name + "." + field.Name;
|
||||
private static string GetPrefix(ContentField field, ContentPart part) {
|
||||
return part.PartDefinition.Name + "." + field.Name;
|
||||
}
|
||||
|
||||
private static string GetDifferentiator(EnumerationField field) => field.Name;
|
||||
private static string GetDifferentiator(EnumerationField field, ContentPart part) {
|
||||
return field.Name;
|
||||
}
|
||||
|
||||
protected override DriverResult Display(ContentPart part, EnumerationField field, string displayType, dynamic shapeHelper) {
|
||||
return ContentShape("Fields_Enumeration", GetDifferentiator(field), () => shapeHelper.Fields_Enumeration());
|
||||
return ContentShape("Fields_Enumeration", GetDifferentiator(field, part),
|
||||
() => shapeHelper.Fields_Enumeration());
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(ContentPart part, EnumerationField field, dynamic shapeHelper) {
|
||||
return ContentShape("Fields_Enumeration_Edit", GetDifferentiator(field), () => {
|
||||
if (part.IsNew() && string.IsNullOrEmpty(field.Value)) {
|
||||
var settings = field.PartFieldDefinition.Settings.GetModel<EnumerationFieldSettings>();
|
||||
if (!string.IsNullOrWhiteSpace(settings.DefaultValue)) {
|
||||
field.SelectedValues = new string[] { settings.DefaultValue };
|
||||
return ContentShape("Fields_Enumeration_Edit", GetDifferentiator(field, part),
|
||||
() => {
|
||||
if (part.IsNew() && String.IsNullOrEmpty(field.Value)) {
|
||||
var settings = field.PartFieldDefinition.Settings.GetModel<EnumerationFieldSettings>();
|
||||
if (!String.IsNullOrWhiteSpace(settings.DefaultValue)) {
|
||||
field.Value = settings.DefaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: field, Prefix: GetPrefix(field, part));
|
||||
});
|
||||
return shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: field, Prefix: GetPrefix(field, part));
|
||||
});
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(ContentPart part, EnumerationField field, IUpdateModel updater, dynamic shapeHelper) {
|
||||
|
||||
@@ -7,16 +7,28 @@ namespace Orchard.Fields.Fields {
|
||||
private const char Separator = ';';
|
||||
|
||||
public string Value {
|
||||
get => Storage.Get<string>()?.Trim(Separator) ?? "";
|
||||
set => Storage.Set(string.IsNullOrWhiteSpace(value)
|
||||
? string.Empty
|
||||
// It is now the responsibility of this field to (re-)add the separators.
|
||||
: Separator + value.Trim(Separator) + Separator);
|
||||
get { return Storage.Get<string>(); }
|
||||
set { Storage.Set(value ?? String.Empty); }
|
||||
}
|
||||
|
||||
public string[] SelectedValues {
|
||||
get => Value?.Split(new[] { Separator }, StringSplitOptions.RemoveEmptyEntries) ?? new string[0];
|
||||
set => Value = value?.Length > 0 ? string.Join(Separator.ToString(), value) : "";
|
||||
get {
|
||||
var value = Value;
|
||||
if(string.IsNullOrWhiteSpace(value)) {
|
||||
return new string[0];
|
||||
}
|
||||
|
||||
return value.Split(new [] { Separator }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
set {
|
||||
if (value == null || value.Length == 0) {
|
||||
Value = String.Empty;
|
||||
}
|
||||
else {
|
||||
Value = Separator + string.Join(Separator.ToString(), value) + Separator;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +169,6 @@
|
||||
<Compile Include="ViewModels\NumericFieldViewModel.cs" />
|
||||
<Compile Include="ViewModels\DateTimeFieldViewModel.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<Content Include="Views\Fields\Input.cshtml" />
|
||||
</ItemGroup>
|
||||
@@ -220,4 +219,4 @@
|
||||
</FlavorProperties>
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -4,30 +4,48 @@
|
||||
|
||||
@{
|
||||
var settings = Model.PartFieldDefinition.Settings.GetModel<EnumerationFieldSettings>();
|
||||
string[] options = (!String.IsNullOrWhiteSpace(settings.Options)) ? settings.Options.Split(new string[] { System.Environment.NewLine }, StringSplitOptions.None) : new string[] { T("Select an option").ToString() };
|
||||
string[] options = (!String.IsNullOrWhiteSpace(settings.Options)) ?
|
||||
settings.Options.Split(new string[] { System.Environment.NewLine }, StringSplitOptions.None)
|
||||
: new string[] { T("Select an option").ToString() };
|
||||
}
|
||||
|
||||
<fieldset>
|
||||
<label for="@Html.FieldIdFor(m => m.Value)" @if (settings.Required) { <text> class="required" </text> }>@Model.DisplayName</label>
|
||||
@switch (settings.ListMode) {
|
||||
case ListMode.Dropdown:
|
||||
@Html.DropDownListFor(m => m.Value, new SelectList(options, Model.SelectedValues.FirstOrDefault()), settings.Required ? new { required = "required" } : null)
|
||||
@Html.DropDownListFor(
|
||||
m => m.Value,
|
||||
new SelectList(options, Model.SelectedValues.FirstOrDefault()),
|
||||
settings.Required ? new { required = "required" } : null)
|
||||
break;
|
||||
|
||||
case ListMode.Radiobutton:
|
||||
foreach (var option in options) {
|
||||
if (string.IsNullOrWhiteSpace(option)) {
|
||||
<label>@Html.RadioButton("Value", "", string.IsNullOrWhiteSpace(Model.SelectedValues.FirstOrDefault()), settings.Required ? new { required = "required" } : null)<i>@T("unset")</i></label>
|
||||
<label>@Html.RadioButton(
|
||||
"Value",
|
||||
"",
|
||||
string.IsNullOrWhiteSpace(Model.SelectedValues.FirstOrDefault()),
|
||||
settings.Required ? new { required = "required" } : null)<i>@T("unset")</i>
|
||||
</label>
|
||||
}
|
||||
else {
|
||||
<label>@Html.RadioButton("Value", option, (option == Model.SelectedValues.FirstOrDefault()), settings.Required ? new { required = "required" } : null)@option</label>
|
||||
<label>@Html.RadioButton(
|
||||
"Value",
|
||||
option,
|
||||
option == Model.SelectedValues.FirstOrDefault(),
|
||||
settings.Required ? new { required = "required" } : null)@option
|
||||
</label>
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ListMode.Listbox:
|
||||
<input name="@Html.FieldNameFor(m => m.SelectedValues)" type="hidden" />
|
||||
@Html.ListBoxFor(m => m.SelectedValues, new MultiSelectList(options, Model.SelectedValues), settings.Required ? new { required = "required" } : null)
|
||||
@Html.ListBoxFor(
|
||||
m => m.SelectedValues,
|
||||
new MultiSelectList(options, Model.SelectedValues),
|
||||
settings.Required ? new { required = "required" } : null)
|
||||
break;
|
||||
|
||||
case ListMode.Checkbox:
|
||||
@@ -37,7 +55,9 @@
|
||||
index++;
|
||||
if (!string.IsNullOrWhiteSpace(option)) {
|
||||
<div>
|
||||
<input type="checkbox" name="@Html.FieldNameFor(m => m.SelectedValues)" value="@option" @((Model.SelectedValues != null && Model.SelectedValues.Contains(option)) ? "checked=\"checked\"" : "") class="check-box" id="@Html.FieldIdFor(m => m.SelectedValues)-@index" />
|
||||
<input type="checkbox" name="@Html.FieldNameFor(m => m.SelectedValues)" value="@option"
|
||||
@((Model.SelectedValues != null && Model.SelectedValues.Contains(option)) ? "checked=\"checked\"" : "")
|
||||
class="check-box" id="@Html.FieldIdFor(m => m.SelectedValues)-@index" />
|
||||
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.SelectedValues)-@index">@option</label>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -1106,17 +1106,17 @@ html.dyn #submit-pager, html.dyn .apply-bulk-actions-auto { display:none; }
|
||||
padding:0;
|
||||
}
|
||||
|
||||
fieldset.publish-button, fieldset.delete-button, fieldset.save-button {
|
||||
fieldset.publish-button, fieldset.delete-button, fieldset.save-button, fieldset.unpublish-button {
|
||||
clear:none;
|
||||
float:left;
|
||||
}
|
||||
fieldset.save-button {
|
||||
clear:left;
|
||||
}
|
||||
fieldset.publish-button {
|
||||
fieldset.publish-button, fieldset.unpublish-button {
|
||||
margin: 0 12px 0 0;
|
||||
padding: 0 12px;
|
||||
border-right:1px solid #ccc;
|
||||
border-right: 1px solid #ccc;
|
||||
}
|
||||
fieldset.delete-button {
|
||||
margin: 0 0 0 12px;
|
||||
|
||||
@@ -17,12 +17,16 @@ namespace Orchard.MediaLibrary.Controllers {
|
||||
[Admin, Themed(false)]
|
||||
public class OEmbedController : Controller {
|
||||
private readonly IMediaLibraryService _mediaLibraryService;
|
||||
private readonly IOEmbedService _oEmbedService;
|
||||
|
||||
public OEmbedController(
|
||||
IOrchardServices services,
|
||||
IMediaLibraryService mediaManagerService) {
|
||||
_mediaLibraryService = mediaManagerService;
|
||||
IMediaLibraryService mediaManagerService,
|
||||
IOEmbedService oEmbedService) {
|
||||
|
||||
Services = services;
|
||||
_mediaLibraryService = mediaManagerService;
|
||||
_oEmbedService = oEmbedService;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
@@ -78,39 +82,9 @@ namespace Orchard.MediaLibrary.Controllers {
|
||||
}
|
||||
}
|
||||
|
||||
var webClient = new WebClient { Encoding = Encoding.UTF8 };
|
||||
try {
|
||||
// <link rel="alternate" href="http://vimeo.com/api/oembed.xml?url=http%3A%2F%2Fvimeo.com%2F23608259" type="text/xml+oembed">
|
||||
viewModel.Content = _oEmbedService.DownloadMediaData(url);
|
||||
|
||||
var source = webClient.DownloadString(url);
|
||||
|
||||
// seek type="text/xml+oembed" or application/xml+oembed
|
||||
var oembedSignature = source.IndexOf("type=\"text/xml+oembed\"", StringComparison.OrdinalIgnoreCase);
|
||||
if (oembedSignature == -1) {
|
||||
oembedSignature = source.IndexOf("type=\"application/xml+oembed\"", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
if (oembedSignature != -1) {
|
||||
var tagStart = source.Substring(0, oembedSignature).LastIndexOf('<');
|
||||
var tagEnd = source.IndexOf('>', oembedSignature);
|
||||
var tag = source.Substring(tagStart, tagEnd - tagStart);
|
||||
var matches = new Regex("href=\"([^\"]+)\"").Matches(tag);
|
||||
if (matches.Count > 0) {
|
||||
var href = matches[0].Groups[1].Value;
|
||||
try {
|
||||
var content = webClient.DownloadString(Server.HtmlDecode(href));
|
||||
viewModel.Content = XDocument.Parse(content);
|
||||
}
|
||||
catch {
|
||||
// bubble exception
|
||||
}
|
||||
}
|
||||
}
|
||||
if (viewModel.Content == null) {
|
||||
viewModel.Content = new XDocument(
|
||||
new XDeclaration("1.0", "utf-8", "yes"),
|
||||
new XElement("oembed")
|
||||
);
|
||||
}
|
||||
var root = viewModel.Content.Root;
|
||||
if (!String.IsNullOrWhiteSpace(url)) {
|
||||
root.El("url", url);
|
||||
|
||||
@@ -208,7 +208,9 @@
|
||||
<Compile Include="Security\MediaAuthorizationEventHandler.cs" />
|
||||
<Compile Include="Services\IMediaLibraryService.cs" />
|
||||
<Compile Include="Providers\IMediaFolderProvider.cs" />
|
||||
<Compile Include="Services\IOEmbedService.cs" />
|
||||
<Compile Include="Services\MediaLibraryService.cs" />
|
||||
<Compile Include="Services\OEmbedService.cs" />
|
||||
<Compile Include="Services\Shapes.cs" />
|
||||
<Compile Include="Services\XmlRpcHandler.cs" />
|
||||
<Compile Include="Settings\MediaLibraryPickerFieldLocalizationEditorEvents.cs" />
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Orchard.MediaLibrary.Services {
|
||||
public interface IOEmbedService : IDependency {
|
||||
XDocument DownloadMediaData(string url);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Orchard.MediaLibrary.Services {
|
||||
public class OEmbedService : IOEmbedService {
|
||||
public XDocument DownloadMediaData(string url) {
|
||||
var webClient = new WebClient { Encoding = Encoding.UTF8 };
|
||||
XDocument doc = null;
|
||||
try {
|
||||
// <link rel="alternate" href="http://vimeo.com/api/oembed.xml?url=http%3A%2F%2Fvimeo.com%2F23608259" type="text/xml+oembed">
|
||||
var source = webClient.DownloadString(url);
|
||||
|
||||
// seek type="text/xml+oembed" or application/xml+oembed
|
||||
var oembedSignature = source.IndexOf("type=\"text/xml+oembed\"", StringComparison.OrdinalIgnoreCase);
|
||||
if (oembedSignature == -1) {
|
||||
oembedSignature = source.IndexOf("type=\"application/xml+oembed\"", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
if (oembedSignature != -1) {
|
||||
var tagStart = source.Substring(0, oembedSignature).LastIndexOf('<');
|
||||
var tagEnd = source.IndexOf('>', oembedSignature);
|
||||
var tag = source.Substring(tagStart, tagEnd - tagStart);
|
||||
var matches = new Regex("href=\"([^\"]+)\"").Matches(tag);
|
||||
if (matches.Count > 0) {
|
||||
var href = matches[0].Groups[1].Value;
|
||||
try {
|
||||
var content = webClient.DownloadString(HttpUtility.HtmlDecode(href));
|
||||
doc = XDocument.Parse(content);
|
||||
} catch {
|
||||
// bubble exception
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
doc = null;
|
||||
}
|
||||
|
||||
if (doc == null) {
|
||||
doc = new XDocument(
|
||||
new XDeclaration("1.0", "utf-8", "yes"),
|
||||
new XElement("oembed")
|
||||
);
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,9 @@ using StackExchange.Redis;
|
||||
using System;
|
||||
|
||||
namespace Orchard.Redis.Caching {
|
||||
|
||||
[OrchardFeature("Orchard.Redis.Caching")]
|
||||
[OrchardSuppressDependency("Orchard.Caching.Services.DefaultCacheStorageProvider")]
|
||||
public class RedisCacheStorageProvider : Component, ICacheStorageProvider {
|
||||
public class RedisCacheStorageProvider : Component, ICacheStorageProviderWithKeyPrefix {
|
||||
public const string ConnectionStringKey = "Orchard.Redis.Cache";
|
||||
|
||||
private readonly ShellSettings _shellSettings;
|
||||
@@ -61,6 +60,10 @@ namespace Orchard.Redis.Caching {
|
||||
_connectionMultiplexer.KeyDeleteWithPrefix(GetLocalizedKey("*"));
|
||||
}
|
||||
|
||||
public void Clear(string key) {
|
||||
_connectionMultiplexer.KeyDeleteWithPrefix(GetLocalizedKey($"{_shellSettings.Name}:{key}"));
|
||||
}
|
||||
|
||||
private string GetLocalizedKey(string key) {
|
||||
return _shellSettings.Name + ":Cache:" + key;
|
||||
}
|
||||
|
||||
@@ -33,30 +33,25 @@ namespace Orchard.Widgets.Drivers {
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Widgets.LayerPart", Model: layerPart, Prefix: Prefix))
|
||||
};
|
||||
|
||||
if (layerPart.Id > 0)
|
||||
results.Add(ContentShape("Widget_DeleteButton",
|
||||
deleteButton => deleteButton));
|
||||
|
||||
return Combined(results.ToArray());
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(LayerPart layerPart, IUpdateModel updater, dynamic shapeHelper) {
|
||||
if(updater.TryUpdateModel(layerPart, Prefix, null, null)) {
|
||||
if (updater.TryUpdateModel(layerPart, Prefix, null, null)) {
|
||||
if (String.IsNullOrWhiteSpace(layerPart.LayerRule)) {
|
||||
layerPart.LayerRule = "true";
|
||||
}
|
||||
|
||||
if (_widgetsService.GetLayers()
|
||||
.Any(l =>
|
||||
.Any(l =>
|
||||
l.Id != layerPart.Id
|
||||
&& String.Equals(l.Name, layerPart.Name, StringComparison.InvariantCultureIgnoreCase))) {
|
||||
&& String.Equals(l.Name, layerPart.Name, StringComparison.InvariantCultureIgnoreCase))) {
|
||||
updater.AddModelError("Name", T("A Layer with the same name already exists"));
|
||||
}
|
||||
|
||||
try {
|
||||
_conditionManager.Matches(layerPart.LayerRule);
|
||||
}
|
||||
catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
updater.AddModelError("Description", T("The rule is not valid: {0}", e.Message));
|
||||
}
|
||||
}
|
||||
@@ -82,7 +77,7 @@ namespace Orchard.Widgets.Drivers {
|
||||
|
||||
var rule = context.Attribute(part.PartDefinition.Name, "LayerRule");
|
||||
if (rule != null) {
|
||||
part.LayerRule = rule;
|
||||
part.LayerRule = rule;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,26 +35,22 @@ namespace Orchard.Widgets.Drivers {
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Widgets.WidgetPart", Model: widgetPart, Prefix: Prefix))
|
||||
};
|
||||
|
||||
if (widgetPart.Id > 0)
|
||||
results.Add(ContentShape("Widget_DeleteButton",
|
||||
deleteButton => deleteButton));
|
||||
|
||||
return Combined(results.ToArray());
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(WidgetPart widgetPart, IUpdateModel updater, dynamic shapeHelper) {
|
||||
updater.TryUpdateModel(widgetPart, Prefix, null, null);
|
||||
|
||||
if(string.IsNullOrWhiteSpace(widgetPart.Title)) {
|
||||
if (string.IsNullOrWhiteSpace(widgetPart.Title)) {
|
||||
updater.AddModelError("Title", T("Title can't be empty."));
|
||||
}
|
||||
|
||||
|
||||
// if there is a name, ensure it's unique
|
||||
if(!string.IsNullOrWhiteSpace(widgetPart.Name)) {
|
||||
if (!string.IsNullOrWhiteSpace(widgetPart.Name)) {
|
||||
widgetPart.Name = widgetPart.Name.ToHtmlName();
|
||||
|
||||
var widgets = _contentManager.Query<WidgetPart, WidgetPartRecord>().Where(x => x.Name == widgetPart.Name && x.Id != widgetPart.Id).Count();
|
||||
if(widgets > 0) {
|
||||
if (widgets > 0) {
|
||||
updater.AddModelError("Name", T("A Widget with the same Name already exists."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,9 +208,6 @@
|
||||
<Content Include="Views\EditorTemplates\Parts.Widgets.LayerPart.cshtml" />
|
||||
<Content Include="Views\EditorTemplates\Parts.Widgets.WidgetPart.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\Widget.DeleteButton.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Web.config" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<Placement>
|
||||
<Place Widget_DeleteButton="Sidebar:25"/>
|
||||
<Place Parts_Widgets_LayerPart="Content:1"/>
|
||||
<Place Parts_Widgets_WidgetPart="Content:1"/>
|
||||
</Placement>
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
<fieldset class="delete-button">
|
||||
<button type="submit" name="submit.Delete" value="@T("Delete")" itemprop="RemoveUrl">@T("Delete")</button>
|
||||
</fieldset>
|
||||
File diff suppressed because it is too large
Load Diff
16
src/Orchard/Data/Conventions/LazyLoadConvention.cs
Normal file
16
src/Orchard/Data/Conventions/LazyLoadConvention.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using FluentNHibernate.Conventions;
|
||||
using FluentNHibernate.Conventions.Instances;
|
||||
|
||||
namespace Orchard.Data.Conventions
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class LazyLoadAttribute : Attribute {
|
||||
}
|
||||
|
||||
public class LazyLoadConvention : AttributePropertyConvention<LazyLoadAttribute> {
|
||||
protected override void Apply(LazyLoadAttribute attribute, IPropertyInstance instance) {
|
||||
instance.LazyLoad();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,6 +154,7 @@
|
||||
<Compile Include="ContentManagement\Extensions\DriverResultExtensions.cs" />
|
||||
<Compile Include="ContentManagement\Handlers\CloneContentContext.cs" />
|
||||
<Compile Include="ContentManagement\IGlobalCriteriaProvider.cs" />
|
||||
<Compile Include="Data\Conventions\LazyLoadConvention.cs" />
|
||||
<Compile Include="Data\MapAsRecordAttribute.cs" />
|
||||
<Compile Include="Data\Migration\Interpreters\PostgreSqlCommandInterpreter.cs" />
|
||||
<Compile Include="Data\NoLockInterceptor.cs" />
|
||||
|
||||
Reference in New Issue
Block a user