diff --git a/src/Umbraco.StorageProviders.AzureBlob/CdnMediaUrlProvider.cs b/src/Umbraco.StorageProviders.AzureBlob/CdnMediaUrlProvider.cs
index 5c7c55d..48d786e 100644
--- a/src/Umbraco.StorageProviders.AzureBlob/CdnMediaUrlProvider.cs
+++ b/src/Umbraco.StorageProviders.AzureBlob/CdnMediaUrlProvider.cs
@@ -1,8 +1,11 @@
using System;
using Microsoft.Extensions.Options;
+using Umbraco.Cms.Core.Configuration.Models;
+using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.PropertyEditors;
using Umbraco.Cms.Core.Routing;
+using Umbraco.Extensions;
namespace Umbraco.StorageProviders.AzureBlob
{
@@ -14,45 +17,89 @@ public class CdnMediaUrlProvider : DefaultMediaUrlProvider
{
private bool _removeMediaFromPath;
private Uri _cdnUrl;
+ private string _mediaPath;
///
- /// Creates a new instance of .
+ /// Initializes a new instance of the class.
///
/// The options.
+ /// The global settings.
+ /// The hosting environment.
/// The media path generators.
/// The URI utility.
- /// options
- public CdnMediaUrlProvider(IOptionsMonitor options,
- MediaUrlGeneratorCollection mediaPathGenerators, UriUtility uriUtility)
+ /// is null.
+ /// is null.
+ /// is null.
+ public CdnMediaUrlProvider(IOptionsMonitor options, IOptionsMonitor globalSettings, IHostingEnvironment hostingEnvironment, MediaUrlGeneratorCollection mediaPathGenerators, UriUtility uriUtility)
+ : this(options, mediaPathGenerators, uriUtility, string.Empty)
+ {
+ if (globalSettings == null) throw new ArgumentNullException(nameof(globalSettings));
+ if (hostingEnvironment == null) throw new ArgumentNullException(nameof(hostingEnvironment));
+
+ _mediaPath = hostingEnvironment.ToAbsolute(globalSettings.CurrentValue.UmbracoMediaPath).EnsureEndsWith('/');
+
+ globalSettings.OnChange((options, name) =>
+ {
+ if (name == Options.DefaultName)
+ {
+ _mediaPath = hostingEnvironment.ToAbsolute(options.UmbracoMediaPath).EnsureEndsWith('/');
+ }
+ });
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The options.
+ /// The media path generators.
+ /// The URI utility.
+ /// is null.
+ [Obsolete("This constructor is obsolete and will be removed in a future version. Use another constructor instead.")]
+ public CdnMediaUrlProvider(IOptionsMonitor options, MediaUrlGeneratorCollection mediaPathGenerators, UriUtility uriUtility)
+ : this(options, mediaPathGenerators, uriUtility, "/media/")
+ { }
+
+ private CdnMediaUrlProvider(IOptionsMonitor options, MediaUrlGeneratorCollection mediaPathGenerators, UriUtility uriUtility, string mediaPath)
: base(mediaPathGenerators, uriUtility)
{
if (options == null) throw new ArgumentNullException(nameof(options));
_cdnUrl = options.CurrentValue.Url;
_removeMediaFromPath = options.CurrentValue.RemoveMediaFromPath;
+ _mediaPath = mediaPath;
- options.OnChange(OptionsOnChange);
+ options.OnChange((options, name) =>
+ {
+ if (name == Options.DefaultName)
+ {
+ _removeMediaFromPath = options.RemoveMediaFromPath;
+ _cdnUrl = options.Url;
+ }
+ });
}
///
public override UrlInfo? GetMediaUrl(IPublishedContent content, string propertyAlias, UrlMode mode, string culture, Uri current)
{
var mediaUrl = base.GetMediaUrl(content, propertyAlias, UrlMode.Relative, culture, current);
- if (mediaUrl == null) return null;
-
- return mediaUrl.IsUrl switch
+ if (mediaUrl?.IsUrl == true)
{
- false => mediaUrl,
- _ => UrlInfo.Url($"{_cdnUrl}/{mediaUrl.Text[(_removeMediaFromPath ? "/media/" : "/").Length..]}", culture)
- };
- }
+ string url = mediaUrl.Text;
- private void OptionsOnChange(CdnMediaUrlProviderOptions options, string name)
- {
- if (name != Options.DefaultName) return;
+ int startIndex = 0;
+ if (_removeMediaFromPath && url.StartsWith(_mediaPath, StringComparison.OrdinalIgnoreCase))
+ {
+ startIndex = _mediaPath.Length;
+ }
+ else if (url.StartsWith('/'))
+ {
+ startIndex = 1;
+ }
+
+ return UrlInfo.Url(_cdnUrl + url[startIndex..], culture);
+ }
- _removeMediaFromPath = options.RemoveMediaFromPath;
- _cdnUrl = options.Url;
+ return mediaUrl;
}
}
}