Merge branch '1.10.x' into dev

# Conflicts:
#	src/Orchard.Web/Core/Orchard.Core.csproj
#	src/Orchard.Web/Modules/Orchard.Localization/Controllers/AdminController.cs
#	src/Orchard.Web/Modules/Orchard.Localization/Views/Parts/Localization.ContentTranslations.SummaryAdmin.cshtml
#	src/Orchard.Web/Modules/Orchard.Redis/OutputCache/RedisOutputCacheStorageProvider.cs
This commit is contained in:
Daniel Stolt
2017-02-09 14:34:21 +01:00
30 changed files with 201 additions and 134 deletions

View File

@@ -84,8 +84,7 @@ namespace Orchard.Core.Common.Drivers {
}
protected override void Exporting(ContentPart part, TextField field, ExportContentContext context) {
if (!String.IsNullOrEmpty(field.Value))
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Text", field.Value);
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Text", field.Value);
}
protected override void Cloning(ContentPart part, TextField originalField, TextField cloneField, CloneContentContext context) {

View File

@@ -118,6 +118,7 @@
<Content Include="Styles\DynamicForms.min.css" />
<Content Include="Styles\menu.dynamicforms-admin.css" />
<Content Include="Styles\menu.dynamicforms.png" />
<Content Include="Styles\recipebuilderstep-forms.css" />
<Content Include="Styles\workflows-activity-add-model-error.css" />
<Content Include="Styles\workflows-activity-dynamic-form-submitted.css" />
<Content Include="Styles\workflows-activity-dynamic-form-validating.css" />
@@ -304,6 +305,7 @@
<Compile Include="Validators\TextAreaValidator.cs" />
<Compile Include="Validators\TextFieldValidator.cs" />
<Compile Include="Validators\UrlFieldValidator.cs" />
<Compile Include="ViewModels\FormExportEntry.cs" />
<Compile Include="ViewModels\FieldValidationSettings.cs" />
<Compile Include="ViewModels\FormBindingSettings.cs" />
<Compile Include="Helpers\ContentTypeDefinitionExtensions.cs" />
@@ -549,6 +551,9 @@
<ItemGroup>
<Content Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\EditorTemplates\BuilderSteps\FormSubmissions.cshtml" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>

View File

@@ -3,12 +3,17 @@ using System.Xml.Linq;
using Orchard.DynamicForms.Services;
using Orchard.Localization;
using Orchard.Recipes.Services;
using System.Collections.Generic;
using Orchard.ContentManagement;
using Orchard.DynamicForms.ViewModels;
namespace Orchard.DynamicForms.Recipes.Builders {
public class FormSubmissionsStep : RecipeBuilderStep {
private readonly IFormService _formService;
public FormSubmissionsStep(IFormService formService) {
_formService = formService;
SelectedForms = new List<string>();
}
public override string Name {
@@ -23,29 +28,43 @@ namespace Orchard.DynamicForms.Recipes.Builders {
get { return T("Exports submitted forms."); }
}
public IList<string> SelectedForms { get; set; }
public override dynamic BuildEditor(dynamic shapeFactory) {
// TODO: Implement an editor that enables the user to select which forms to export.
return null;
return UpdateEditor(shapeFactory, null);
}
public override dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater) {
List<FormExportEntry> forms = new List<FormExportEntry>();
if (updater != null && updater.TryUpdateModel(forms, Prefix, null, null)) {
SelectedForms = forms.Where(x => x.Export).Select(x => x.FormName).ToList();
}
else {
forms = _formService.GetSubmissions().OrderBy(x => x.FormName).GroupBy(y => y.FormName)
.Select(x => new FormExportEntry { FormName = x.FirstOrDefault().FormName })
.ToList();
}
return shapeFactory.EditorTemplate(TemplateName: "BuilderSteps/FormSubmissions", Model: forms, Prefix: Prefix);
}
public override void Build(BuildContext context) {
var submissions = _formService.GetSubmissions().ToArray();
if (SelectedForms.Count() > 0) {
var root = new XElement("Forms");
context.RecipeDocument.Element("Orchard").Add(root);
if (!submissions.Any()) {
return;
}
var forms = submissions.GroupBy(x => x.FormName);
var root = new XElement("Forms");
context.RecipeDocument.Element("Orchard").Add(root);
foreach (var form in forms) {
root.Add(new XElement("Form",
new XAttribute("Name", form.Key),
new XElement("Submissions", form.Select(submission =>
new XElement("Submission",
new XAttribute("CreatedUtc", submission.CreatedUtc),
new XCData(submission.FormData))))));
foreach (var form in SelectedForms) {
var submissions = _formService.GetSubmissions(form);
if (submissions.Count() > 0) {
root.Add(new XElement("Form",
new XAttribute("Name", form),
new XElement("Submissions", submissions.Select(submission =>
new XElement("Submission",
new XAttribute("CreatedUtc", submission.CreatedUtc),
new XCData(submission.FormData))))));
}
}
}
}
}

View File

@@ -0,0 +1,9 @@
fieldset.recipe-builder-step-form-submissions table.items {
width: 500px;
margin: 0;
}
fieldset.recipe-builder-step-form-submissions table.items td,
fieldset.recipe-builder-step-form-submissions table.items thead tr.sub th {
padding: 0 12px;
}

View File

@@ -0,0 +1,6 @@
namespace Orchard.DynamicForms.ViewModels {
public class FormExportEntry {
public string FormName { get; set; }
public bool Export { get; set; }
}
}

View File

@@ -0,0 +1,35 @@
@model List<FormExportEntry>
@using Orchard.DynamicForms.ViewModels;
@{
Style.Include("recipebuilderstep-forms.css");
}
<div>
<table class="items">
<thead>
<tr>
<th>@T("Form")</th>
<th>
<input type="checkbox" class="check-all-in-column" />
@T("Select All")
</th>
</tr>
</thead>
<tbody>
@for (int index = 0; index < Model.Count(); index++) {
var entry = Model.ElementAt(index);
<tr>
<td>@entry.FormName</td>
<td>
<input type="hidden" name="@Html.NameFor(m => m[index].FormName)" value="@entry.FormName" />
<input type="checkbox" class="check-data" name="@Html.NameFor(m => m[index].Export)" value="true" />
</td>
</tr>
}
</tbody>
</table>
@Html.Hint(T("Choose the forms to include in the export file"))
</div>

View File

@@ -62,8 +62,7 @@ namespace Orchard.Fields.Drivers {
}
protected override void Exporting(ContentPart part, BooleanField field, ExportContentContext context) {
if (field.Value.HasValue)
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Value", field.Value);
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Value", field.Value);
}
protected override void Cloning(ContentPart part, BooleanField originalField, BooleanField cloneField, CloneContentContext context) {

View File

@@ -169,9 +169,7 @@ namespace Orchard.Fields.Drivers {
}
protected override void Exporting(ContentPart part, DateTimeField field, ExportContentContext context) {
var value = field.Storage.Get<DateTime>(null);
if (value != DateTime.MinValue)
context.Element(GetPrefix(field, part)).SetAttributeValue("Value", XmlConvert.ToString(value, XmlDateTimeSerializationMode.Utc));
context.Element(GetPrefix(field, part)).SetAttributeValue("Value", XmlConvert.ToString(field.Storage.Get<DateTime>(null), XmlDateTimeSerializationMode.Utc));
}
protected override void Cloning(ContentPart part, DateTimeField originalField, DateTimeField cloneField, CloneContentContext context) {

View File

@@ -63,8 +63,7 @@ namespace Orchard.Fields.Drivers {
}
protected override void Exporting(ContentPart part, EnumerationField field, ExportContentContext context) {
if (!String.IsNullOrEmpty(field.Value))
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Value", field.Value);
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Value", field.Value);
}
protected override void Cloning(ContentPart part, EnumerationField originalField, EnumerationField cloneField, CloneContentContext context) {

View File

@@ -61,8 +61,7 @@ namespace Orchard.Fields.Drivers {
}
protected override void Exporting(ContentPart part, InputField field, ExportContentContext context) {
if (!String.IsNullOrEmpty(field.Value))
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Value", field.Value);
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Value", field.Value);
}
protected override void Cloning(ContentPart part, InputField originalField, InputField cloneField, CloneContentContext context) {

View File

@@ -75,11 +75,9 @@ namespace Orchard.Fields.Drivers {
}
protected override void Exporting(ContentPart part, LinkField field, ExportContentContext context) {
if (!String.IsNullOrEmpty(field.Text) || !String.IsNullOrEmpty(field.Value) || !String.IsNullOrEmpty(field.Target)) {
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Text", field.Text);
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Url", field.Value);
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Target", field.Target);
}
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Text", field.Text);
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Url", field.Value);
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Target", field.Target);
}
protected override void Cloning(ContentPart part, LinkField originalField, LinkField cloneField, CloneContentContext context) {

View File

@@ -106,8 +106,7 @@ namespace Orchard.Fields.Drivers {
}
protected override void Exporting(ContentPart part, NumericField field, ExportContentContext context) {
if (field.Value.HasValue)
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Value", field.Value.Value.ToString(CultureInfo.InvariantCulture));
context.Element(field.FieldDefinition.Name + "." + field.Name).SetAttributeValue("Value", !field.Value.HasValue ? String.Empty : field.Value.Value.ToString(CultureInfo.InvariantCulture));
}
protected override void Cloning(ContentPart part, NumericField originalField, NumericField cloneField, CloneContentContext context) {

View File

@@ -3,5 +3,6 @@
namespace Orchard.Layouts.Framework.Harvesters {
public class HarvestElementsContext {
public IContent Content { get; set; }
public bool IsHarvesting { get; set; }
}
}

View File

@@ -13,7 +13,6 @@ namespace Orchard.Layouts.Providers {
public class BlueprintElementHarvester : Component, IElementHarvester {
private readonly Work<IElementBlueprintService> _elementBlueprintService;
private readonly Work<IElementManager> _elementManager;
private bool _isHarvesting;
public BlueprintElementHarvester(Work<IElementBlueprintService> elementBlueprintService, Work<IElementManager> elementManager) {
_elementBlueprintService = elementBlueprintService;
@@ -21,15 +20,14 @@ namespace Orchard.Layouts.Providers {
}
public IEnumerable<ElementDescriptor> HarvestElements(HarvestElementsContext context) {
if (_isHarvesting)
if (context.IsHarvesting)
return Enumerable.Empty<ElementDescriptor>();
_isHarvesting = true;
var blueprints = _elementBlueprintService.Value.GetBlueprints().ToArray();
var query =
from blueprint in blueprints
let describeContext = new DescribeElementsContext {Content = context.Content, CacheVaryParam = "Blueprints"}
let describeContext = new DescribeElementsContext {Content = context.Content, CacheVaryParam = "Blueprints", IsHarvesting = true }
let baseElementDescriptor = _elementManager.Value.GetElementDescriptorByTypeName(describeContext, blueprint.BaseElementTypeName)
let baseElement = _elementManager.Value.ActivateElement(baseElementDescriptor)
select new ElementDescriptor(
@@ -48,9 +46,7 @@ namespace Orchard.Layouts.Providers {
}
};
var descriptors = query.ToArray();
_isHarvesting = false;
return descriptors;
return query.ToArray();
}
private static string GetCategory(ElementBlueprint blueprint) {

View File

@@ -4,6 +4,7 @@ namespace Orchard.Layouts.Services {
public class DescribeElementsContext {
public IContent Content { get; set; }
public string CacheVaryParam { get; set; }
public bool IsHarvesting { get; set; }
public static readonly DescribeElementsContext Empty = new DescribeElementsContext();
}

View File

@@ -40,7 +40,8 @@ namespace Orchard.Layouts.Services {
var cacheKey = String.Format("LayoutElementTypes-{0}-{1}", contentType ?? "AnyType", context.CacheVaryParam);
return _cacheManager.Get(cacheKey, true, acquireContext => {
var harvesterContext = new HarvestElementsContext {
Content = context.Content
Content = context.Content,
IsHarvesting = context.IsHarvesting
};
var query =
from harvester in _elementHarvesters.Value

View File

@@ -21,35 +21,45 @@ namespace Orchard.Localization.Drivers {
}
protected override DriverResult Display(LocalizationPart part, string displayType, dynamic shapeHelper) {
var masterId = part.HasTranslationGroup
? part.Record.MasterContentItemId
: part.Id;
return Combined(
ContentShape("Parts_Localization_ContentTranslations",
() => shapeHelper.Parts_Localization_ContentTranslations(Id: part.ContentItem.Id, MasterId: masterId, Culture: GetCulture(part), Localizations: GetDisplayLocalizations(part, VersionOptions.Published))),
() => shapeHelper.Parts_Localization_ContentTranslations(Id: part.ContentItem.Id, MasterId: ActualMasterId(part), Culture: GetCulture(part), Localizations: GetDisplayLocalizations(part, VersionOptions.Published))),
ContentShape("Parts_Localization_ContentTranslations_Summary",
() => shapeHelper.Parts_Localization_ContentTranslations_Summary(Id: part.ContentItem.Id, MasterId: masterId, Culture: GetCulture(part), Localizations: GetDisplayLocalizations(part, VersionOptions.Published))),
() => shapeHelper.Parts_Localization_ContentTranslations_Summary(Id: part.ContentItem.Id, MasterId: ActualMasterId(part), Culture: GetCulture(part), Localizations: GetDisplayLocalizations(part, VersionOptions.Published))),
ContentShape("Parts_Localization_ContentTranslations_SummaryAdmin", () => {
var siteCultures = _cultureManager.ListCultures();
return shapeHelper.Parts_Localization_ContentTranslations_SummaryAdmin(Id: part.ContentItem.Id, MasterId: masterId, Culture: GetCulture(part), Localizations: GetDisplayLocalizations(part, VersionOptions.Latest), SiteCultures: siteCultures);
return shapeHelper.Parts_Localization_ContentTranslations_SummaryAdmin(Id: part.ContentItem.Id, MasterId: ActualMasterId(part), Culture: GetCulture(part), Localizations: GetDisplayLocalizations(part, VersionOptions.Latest), SiteCultures: siteCultures);
})
);
}
private int ActualMasterId(LocalizationPart part) {
var masterId = part.HasTranslationGroup
? part.Record.MasterContentItemId
: part.Id;
if (_contentManager.Get(masterId, VersionOptions.Latest) == null) {
//the original MasterContentItem has been deleted
masterId = part.Id;
}
return masterId;
}
protected override DriverResult Editor(LocalizationPart part, dynamic shapeHelper) {
var localizations = GetEditorLocalizations(part).ToList();
var missingCultures = part.HasTranslationGroup ?
RetrieveMissingCultures(part.MasterContentItem.As<LocalizationPart>(), true) :
var masterContentItem = _contentManager.Get(part.Record.MasterContentItemId, VersionOptions.Latest);
var missingCultures = part.HasTranslationGroup && masterContentItem != null ?
RetrieveMissingCultures(masterContentItem.As<LocalizationPart>(), true) :
RetrieveMissingCultures(part, part.Culture != null);
var model = new EditLocalizationViewModel {
SelectedCulture = GetCulture(part),
MissingCultures = missingCultures,
ContentItem = part,
MasterContentItem = part.HasTranslationGroup ? part.MasterContentItem : null,
MasterContentItem = masterContentItem,
ContentLocalizations = new ContentLocalizationsViewModel(part) { Localizations = localizations }
};
@@ -70,7 +80,7 @@ namespace Orchard.Localization.Drivers {
}
private List<string> RetrieveMissingCultures(LocalizationPart part, bool excludePartCulture) {
var editorLocalizations = GetEditorLocalizations(part);
var editorLocalizations = GetEditorLocalizations(part.MasterContentItem != null ? part.MasterContentItem.As<LocalizationPart>() : part);
var cultures = _cultureManager
.ListCultures()

View File

@@ -16,7 +16,7 @@ var localizationLinks = Html.UnorderedList(localizations, (c, i) => Html.ItemEdi
}
@if (Model.Culture != null && !((IEnumerable<string>)Model.SiteCultures).All(c => c == Model.Culture || localizations.Any(l => c == l.Culture.Culture)))
{
<div class="add-localization">@Html.ActionLink(T("+ New translation").Text, "Translate", "Admin", new { area = "Orchard.Localization", id = Model.Id }, new { itemprop = "UnsafeUrl" })</div>
<div class="add-localization">@Html.ActionLink(T("+ New translation").Text, "Translate", "Admin", new { area = "Orchard.Localization", id = Model.MasterId }, new { itemprop = "UnsafeUrl" })</div>
}
</div>
}

View File

@@ -1,25 +1,40 @@
using System;
using Orchard.ContentManagement.Handlers;
using Orchard.Data;
using Orchard.MediaLibrary.Services;
using Orchard.MediaLibrary.Models;
using System.IO;
using Orchard.FileSystems.Media;
using System.Linq;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Handlers;
using Orchard.ContentManagement.MetaData;
using Orchard.Core.Title.Models;
using Orchard.Data;
using Orchard.FileSystems.Media;
using Orchard.MediaLibrary.Models;
using Orchard.MediaLibrary.Services;
namespace Orchard.MediaLibrary.Handlers {
public class MediaPartHandler : ContentHandler {
private readonly IMediaLibraryService _mediaLibraryService;
private readonly IStorageProvider _storageProvider;
private readonly IContentDefinitionManager _contentDefinitionManager;
public MediaPartHandler(
IStorageProvider storageProvider,
IMediaLibraryService mediaLibraryService,
IRepository<MediaPartRecord> repository) {
IRepository<MediaPartRecord> repository,
IContentDefinitionManager contentDefinitionManager) {
_storageProvider = storageProvider;
_mediaLibraryService = mediaLibraryService;
_contentDefinitionManager = contentDefinitionManager;
Filters.Add(StorageFilter.For(repository));
Filters.Add(new ActivatingFilter<TitlePart>(contentType => {
var typeDefinition = _contentDefinitionManager.GetTypeDefinition(contentType);
// To avoid NRE when the handler runs for ad-hoc content types, e.g. MediaLibraryExplorer.
return typeDefinition == null ?
false :
typeDefinition.Parts.Any(contentTypePartDefinition =>
contentTypePartDefinition.PartDefinition.Name == typeof(MediaPart).Name);
}));
OnRemoving<MediaPart>((context, part) => RemoveMedia(part));
OnLoaded<MediaPart>((context, part) => {
if (!String.IsNullOrEmpty(part.FileName)) {

View File

@@ -1,8 +1,10 @@
using System;
using Orchard.ContentManagement;
using Orchard.ContentManagement.FieldStorage.InfosetStorage;
using Orchard.ContentManagement.Handlers;
using Orchard.ContentManagement.Utilities;
using Orchard.Core.Title.Models;
using Orchard.MediaLibrary.Handlers;
namespace Orchard.MediaLibrary.Models {
public class MediaPart : ContentPart<MediaPartRecord> {
@@ -11,6 +13,8 @@ namespace Orchard.MediaLibrary.Models {
/// <summary>
/// Gets or sets the title of the media.
/// This adds an implicit dependency on <see cref="TitlePart"/> which will be resolved by an
/// <see cref="ActivatingFilter{TPart}"/> in the <see cref="MediaPartHandler"/>.
/// </summary>
public string Title {
get { return ContentItem.As<TitlePart>().Title; }
@@ -63,7 +67,7 @@ namespace Orchard.MediaLibrary.Models {
/// Gets the public Url of the media if stored locally.
/// </summary>
public string MediaUrl {
get { return _publicUrl.Value; }
get { return _publicUrl.Value; }
}
/// <summary>

View File

@@ -58,7 +58,7 @@ namespace Orchard.Redis.Caching {
}
public void Clear() {
Database.KeyDeleteWithPrefix(GetLocalizedKey("*"));
_connectionMultiplexer.KeyDeleteWithPrefix(GetLocalizedKey("*"));
}
private string GetLocalizedKey(string key) {

View File

@@ -1,41 +0,0 @@
using System;
using StackExchange.Redis;
namespace Orchard.Redis.Extensions {
public static class RedisDatabaseExtensions {
public static void KeyDeleteWithPrefix(this IDatabase database, string prefix) {
if (database == null) {
throw new ArgumentException("Database cannot be null", "database");
}
if (string.IsNullOrWhiteSpace(prefix)) {
throw new ArgumentException("Prefix cannot be empty", "database");
}
database.ScriptEvaluate(@"
local keys = redis.call('keys', ARGV[1])
for i=1,#keys,5000 do
redis.call('del', unpack(keys, i, math.min(i+4999, #keys)))
end", values: new RedisValue[] { prefix });
}
public static int KeyCount(this IDatabase database, string prefix) {
if (database == null) {
throw new ArgumentException("Database cannot be null", "database");
}
if (string.IsNullOrWhiteSpace(prefix)) {
throw new ArgumentException("Prefix cannot be empty", "database");
}
var retVal = database.ScriptEvaluate("return table.getn(redis.call('keys', ARGV[1]))", values: new RedisValue[] { prefix });
if (retVal.IsNull) {
return 0;
}
return (int)retVal;
}
}
}

View File

@@ -113,7 +113,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Caching\RedisCacheStorageProvider.cs" />
<Compile Include="Extensions\RedisDatabaseExtensions.cs" />
<Compile Include="Extensions\RedisConnectionExtensions.cs" />
<Compile Include="Configuration\IRedisConnectionProvider.cs" />
<Compile Include="Configuration\RedisConnectionProvider.cs" />
<Compile Include="MessageBus\RedisMessageBusBroker.cs" />

View File

@@ -86,7 +86,7 @@ namespace Orchard.Redis.OutputCache {
return;
}
Database.KeyDeleteWithPrefix(GetLocalizedKey("*"));
Database.KeyDelete(GetPrefixedKeys().Select(key => (RedisKey)key).ToArray());
}
public CacheItem GetCacheItem(string key) {
@@ -126,7 +126,7 @@ namespace Orchard.Redis.OutputCache {
return 0;
}
return Database.KeyCount(GetLocalizedKey("*"));
return GetPrefixedKeys().Count();
}
/// <summary>
@@ -147,19 +147,19 @@ namespace Orchard.Redis.OutputCache {
return new string[0];
}
var prefix = GetLocalizedKey("");
return GetPrefixedKeys().Select(x => x.Substring(prefix.Length));
}
private IEnumerable<string> GetPrefixedKeys() {
// prevent the same request from computing the list twice (count + list)
if (_keysCache == null) {
_keysCache = new HashSet<string>();
var prefix = GetLocalizedKey("");
foreach (var endPoint in _connectionMultiplexer.GetEndPoints()) {
var server = _connectionMultiplexer.GetServer(endPoint);
foreach (var key in server.Keys(pattern: GetLocalizedKey("*"))) {
_keysCache.Add(key.ToString().Substring(prefix.Length));
}
var keys = _connectionMultiplexer.GetKeys(GetLocalizedKey("*"));
foreach (var key in keys) {
_keysCache.Add(key);
}
}
return _keysCache;
}

View File

@@ -117,13 +117,10 @@ namespace Orchard.Taxonomies.Drivers {
}
protected override void Exporting(ContentPart part, TaxonomyField field, ExportContentContext context) {
var appliedTerms = _taxonomyService.GetTermsForContentItem(part.ContentItem.Id, field.Name);
var appliedTerms = _taxonomyService.GetTermsForContentItem(part.ContentItem.Id, field.Name);
// stores all content items associated to this field
var termIdentities = appliedTerms.Select(x => Services.ContentManager.GetItemMetadata(x).Identity.ToString()).ToArray();
if (termIdentities.Any())
context.Element(XmlConvert.EncodeLocalName(field.FieldDefinition.Name + "." + field.Name)).SetAttributeValue("Terms", String.Join(",", termIdentities));
context.Element(XmlConvert.EncodeLocalName(field.FieldDefinition.Name + "." + field.Name)).SetAttributeValue("Terms", String.Join(",", termIdentities));
}
protected override void Importing(ContentPart part, TaxonomyField field, ImportContentContext context) {

View File

@@ -70,7 +70,7 @@ namespace Orchard.DisplayManagement.Descriptors.ShapeAttributeStrategy {
catch(TargetInvocationException e) {
// Throwing a TIE here will probably kill the web process
// in Azure. For unknown reasons.
throw e.InnerException;
throw new Exception(string.Concat("TargetInvocationException ", methodInfo.Name), e.InnerException);
}
}

View File

@@ -2,13 +2,15 @@
using System.Web;
using System.Web.Mvc;
using Orchard.Utility.Extensions;
using Orchard.Environment.Configuration;
namespace Orchard.Mvc.Extensions {
public static class ControllerExtensions {
public static ActionResult RedirectLocal(this Controller controller, string redirectUrl, Func<ActionResult> invalidUrlBehavior) {
if (!string.IsNullOrWhiteSpace(redirectUrl) && controller.Request.IsLocalUrl(redirectUrl)) {
return new RedirectResult(redirectUrl);
return RedirectWithTenantPrefix(redirectUrl, controller);
}
return invalidUrlBehavior != null ? invalidUrlBehavior() : null;
}
@@ -18,10 +20,25 @@ namespace Orchard.Mvc.Extensions {
public static ActionResult RedirectLocal(this Controller controller, string redirectUrl, string defaultUrl) {
if (controller.Request.IsLocalUrl(redirectUrl)) {
return new RedirectResult(redirectUrl);
return RedirectWithTenantPrefix(redirectUrl, controller);
}
return new RedirectResult(defaultUrl ?? "~/");
return RedirectWithTenantPrefix(defaultUrl ?? "~/", controller);
}
private static ActionResult RedirectWithTenantPrefix(string redirectUrl, Controller controller) {
if (redirectUrl.StartsWith("~/")) {
ShellSettings settings;
var context = controller.ControllerContext.GetWorkContext();
if (context != null &&
context.TryResolve<ShellSettings>(out settings) &&
!string.IsNullOrWhiteSpace(settings.RequestUrlPrefix)) {
redirectUrl = VirtualPathUtility.ToAbsolute(redirectUrl, controller.Request.ApplicationPath.TrimEnd('/') + "/" + settings.RequestUrlPrefix);
}
}
return new RedirectResult(redirectUrl);
}
}
}

View File

@@ -23,10 +23,10 @@ namespace Orchard.UI.Navigation {
/// <param name="page">The page parameter.</param>
/// <param name="pageSize">The page size parameter.</param>
public Pager(ISite site, int? page, int? pageSize) {
Page = (int) (page != null ? (page > 0 ? page : PageDefault) : PageDefault);
PageSize = pageSize ?? site.PageSize;
Page = page == null || page == 0 ? PageDefault : page.Value;
if (site.MaxPageSize > 0 && PageSize > site.MaxPageSize) {
PageSize = pageSize ?? site.PageSize;
if (site.MaxPageSize > 0 && (PageSize == 0 || PageSize > site.MaxPageSize)) {
PageSize = site.MaxPageSize;
}
}

View File

@@ -22,8 +22,8 @@
</ToolsOptionsCategory>
<ToolsOptionsCategory name="TextEditor">
<ToolsOptionsSubCategory name="CSharp-Specific">
<PropertyValue name="AddImport_SuggestForTypesInNuGetPackages">0</PropertyValue>
<PropertyValue name="AddImport_SuggestForTypesInReferenceAssemblies">0</PropertyValue>
<PropertyValue name="AddImport_SuggestForTypesInNuGetPackages">1</PropertyValue>
<PropertyValue name="AddImport_SuggestForTypesInReferenceAssemblies">1</PropertyValue>
<PropertyValue name="AutoComment">1</PropertyValue>
<PropertyValue name="AutoInsertAsteriskForNewLinesOfBlockComments">1</PropertyValue>
<PropertyValue name="CSharpClosedFileDiagnostics">-1</PropertyValue>
@@ -141,10 +141,10 @@
<PropertyValue name="EnableExpandPrecedence">false</PropertyValue>
<PropertyValue name="EnableExpandScopes">false</PropertyValue>
<PropertyValue name="EnableExtractFunction">false</PropertyValue>
<PropertyValue name="EnableSQLiteStoreEngine">false</PropertyValue>
<PropertyValue name="EnableSQLiteStoreEngine">true</PropertyValue>
<PropertyValue name="EnableSingleFileISense">true</PropertyValue>
<PropertyValue name="EnableSingleFileISenseSquiggles">false</PropertyValue>
<PropertyValue name="EnumerateCommentTasks">false</PropertyValue>
<PropertyValue name="EnumerateCommentTasks">true</PropertyValue>
<PropertyValue name="GroupBrackets">true</PropertyValue>
<PropertyValue name="HideExperimentalAd">true</PropertyValue>
<PropertyValue name="HighlightMatchingTokens">true</PropertyValue>