Compare commits

...

3 Commits

Author SHA1 Message Date
Benedek Farkas
5e8787b1fa Removing obsolete TermPart.SortObsolete (and TermsComparer) from Taxonomies 2026-01-07 22:06:02 +01:00
Milán Keszthelyi
165505b1db #8862: Preventing the SQL Server Service Broker feature from being enabled when not using SQL Server (Lombiq Technologies: ORCH-309) (#8875)
Some checks failed
Build Crowdin Translation Packages / build-crowdin-translation-packages (push) Has been cancelled
Compile / Compile .NET solution (push) Has been cancelled
Compile / Compile Client-side Assets (push) Has been cancelled
SpecFlow Tests / SpecFlow Tests (push) Has been cancelled
2025-12-09 00:05:04 +01:00
Benedek Farkas
d9d071115c ResourceManager skips rendering a resource without an URL (#8876) 2025-12-04 21:54:36 +01:00
4 changed files with 100 additions and 80 deletions

View File

@@ -130,6 +130,7 @@
<Compile Include="Services\IHostNameProvider.cs" />
<Compile Include="Services\MessageBusNotificationProvider.cs" />
<Compile Include="Handler\MessageBusHandler.cs" />
<Compile Include="Services\SqlServerServiceBrokerFeatureGuard.cs" />
<Compile Include="SqlServerBrokerMigrations.cs" />
<Compile Include="Models\MessageRecord.cs" />
<Compile Include="Services\DefaultMessageBus.cs" />

View File

@@ -0,0 +1,96 @@
using System;
using System.Web.Mvc;
using Orchard.Environment;
using Orchard.Environment.Configuration;
using Orchard.Environment.Extensions.Models;
using Orchard.Environment.Features;
using Orchard.Localization;
using Orchard.Mvc;
using Orchard.Mvc.Filters;
using Orchard.UI.Notify;
namespace Orchard.MessageBus.Services
{
/// <summary>
/// Prevents the SQL Server Service Broker feature from being enabled for tenants that are not using Microsoft SQL
/// Server as their database provider.
/// </summary>
/// <remarks>
/// The implementation is hackish but there seems to be no other way: if it would use <see cref="INotifier"/> it
/// wouldn't work since <see cref="NotifyFilter"/> that writes out notifications to TempData runs before feature
/// events are raised. Thus we have to manually add the messages to TempData, just as the filter would do.
/// </remarks>
public class SqlServerServiceBrokerFeatureGuard : FilterProvider, IFeatureEventHandler, IActionFilter
{
private const string FeatureId = "Orchard.MessageBus.SqlServerServiceBroker";
private const string TempDataKey = FeatureId + ".TempData";
private readonly ShellSettings _shellSettings;
private readonly IFeatureManager _featureManager;
private readonly IHttpContextAccessor _hca;
public Localizer T { get; set; }
public SqlServerServiceBrokerFeatureGuard(
ShellSettings shellSettings,
IFeatureManager featureManager,
IHttpContextAccessor hca)
{
_shellSettings = shellSettings;
_featureManager = featureManager;
_hca = hca;
T = NullLocalizer.Instance;
}
void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext) { }
void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext)
{
var httpContext = _hca.Current();
if (httpContext == null) return;
httpContext.Items[TempDataKey] = filterContext.Controller.TempData;
}
public void Installing(Feature feature) { }
public void Installed(Feature feature) { }
public void Enabling(Feature feature) { }
public void Enabled(Feature feature)
{
if (feature.Descriptor.Id != FeatureId)
return;
if (!_shellSettings.DataProvider.Equals("SqlServer", StringComparison.OrdinalIgnoreCase))
{
_featureManager.DisableFeatures(new[] { FeatureId }, force: true);
AddNotification(
T("The SQL Server Service Broker cannot be enabled because it requires Microsoft SQL Server."),
NotifyType.Error);
}
}
public void Disabling(Feature feature) { }
public void Disabled(Feature feature) { }
public void Uninstalling(Feature feature) { }
public void Uninstalled(Feature feature) { }
private void AddNotification(LocalizedString message, NotifyType notifyType = NotifyType.Warning)
{
var tempDataDictionary = _hca.Current()?.Items[TempDataKey];
if (tempDataDictionary == null) return;
((TempDataDictionary)tempDataDictionary)["messages"] +=
$"{notifyType}:{message.Text}{System.Environment.NewLine}-{System.Environment.NewLine}";
}
}
}

View File

@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
@@ -83,83 +82,5 @@ namespace Orchard.Taxonomies.Models
{
return terms.OrderBy(term => term.FullWeight);
}
[Obsolete]
public static IEnumerable<TermPart> SortObsolete(IEnumerable<TermPart> terms)
{
var list = terms.ToList();
var index = list.ToDictionary(x => x.FullPath);
return list.OrderBy(x => x, new TermsComparer(index));
}
[Obsolete]
private class TermsComparer : IComparer<TermPart>
{
private readonly IDictionary<string, TermPart> _index;
public TermsComparer(IDictionary<string, TermPart> index)
{
_index = index;
}
public int Compare(TermPart x, TermPart y)
{
// if two nodes have the same parent, then compare by weight, then by path
// /1/2/3 vs /1/2/4 => 3 vs 4
if (x.Path == y.Path)
{
var weight = y.Weight.CompareTo(x.Weight);
if (weight != 0)
{
return weight;
}
// if same parent path and same weight, compare by name
return string.Compare(x.Name, y.Name, StringComparison.OrdinalIgnoreCase);
}
// if two nodes have different parents
// if the two nodes have the same root, the deeper is after (i.e. one starts with the other)
// /1/2 vs /1/2/3 => /1/2 first
if (x.FullPath.StartsWith(y.FullPath, StringComparison.OrdinalIgnoreCase))
{
return 1;
}
if (y.FullPath.StartsWith(x.FullPath, StringComparison.OrdinalIgnoreCase))
{
return -1;
}
// otherwise compare first none matching parent
// /1/2 vs /1/3 => 2 vs 3
// /2/3 vs /4 => 2 vs 4
var xPath = x.FullPath.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
var yPath = y.FullPath.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
string xFullPath = "", yFullPath = "";
for (var i = 0; i < Math.Min(xPath.Length, yPath.Length); i++)
{
xFullPath += "/" + xPath[i];
yFullPath += "/" + yPath[i];
if (!xFullPath.Equals(yFullPath, StringComparison.OrdinalIgnoreCase))
{
var xParent = _index[xFullPath];
var yParent = _index[yFullPath];
return Compare(xParent, yParent);
}
}
return 0;
}
}
}
}
}

View File

@@ -97,6 +97,8 @@ namespace Orchard.UI.Resources
public static void WriteResource(TextWriter writer, ResourceDefinition resource, string url, string condition, Dictionary<string, string> attributes)
{
if (string.IsNullOrEmpty(url)) return;
if (!string.IsNullOrEmpty(condition))
{
if (condition == NotIE)