Merge remote-tracking branch 'origin/netcore/dev' into netcore/feature/AB4919-untable-umbraco-context
This commit is contained in:
7
src/Umbraco.Abstractions/Models/IImageUrlGenerator.cs
Normal file
7
src/Umbraco.Abstractions/Models/IImageUrlGenerator.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
public interface IImageUrlGenerator
|
||||
{
|
||||
string GetImageUrl(ImageUrlGenerationOptions options);
|
||||
}
|
||||
}
|
||||
66
src/Umbraco.Abstractions/Models/ImageUrlGenerationOptions.cs
Normal file
66
src/Umbraco.Abstractions/Models/ImageUrlGenerationOptions.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// These are options that are passed to the IImageUrlGenerator implementation to determine
|
||||
/// the propery URL that is needed
|
||||
/// </summary>
|
||||
public class ImageUrlGenerationOptions
|
||||
{
|
||||
public ImageUrlGenerationOptions (string imageUrl)
|
||||
{
|
||||
ImageUrl = imageUrl;
|
||||
}
|
||||
|
||||
public string ImageUrl { get; }
|
||||
public int? Width { get; set; }
|
||||
public int? Height { get; set; }
|
||||
public decimal? WidthRatio { get; set; }
|
||||
public decimal? HeightRatio { get; set; }
|
||||
public int? Quality { get; set; }
|
||||
public string ImageCropMode { get; set; }
|
||||
public string ImageCropAnchor { get; set; }
|
||||
public bool DefaultCrop { get; set; }
|
||||
public FocalPointPosition FocalPoint { get; set; }
|
||||
public CropCoordinates Crop { get; set; }
|
||||
public string CacheBusterValue { get; set; }
|
||||
public string FurtherOptions { get; set; }
|
||||
public bool UpScale { get; set; } = true;
|
||||
public string AnimationProcessMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The focal point position, in whatever units the registered IImageUrlGenerator uses,
|
||||
/// typically a percentage of the total image from 0.0 to 1.0.
|
||||
/// </summary>
|
||||
public class FocalPointPosition
|
||||
{
|
||||
public FocalPointPosition (decimal top, decimal left)
|
||||
{
|
||||
Left = left;
|
||||
Top = top;
|
||||
}
|
||||
|
||||
public decimal Left { get; }
|
||||
public decimal Top { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The bounds of the crop within the original image, in whatever units the registered
|
||||
/// IImageUrlGenerator uses, typically a percentage between 0 and 100.
|
||||
/// </summary>
|
||||
public class CropCoordinates
|
||||
{
|
||||
public CropCoordinates (decimal x1, decimal y1, decimal x2, decimal y2)
|
||||
{
|
||||
X1 = x1;
|
||||
Y1 = y1;
|
||||
X2 = x2;
|
||||
Y2 = y2;
|
||||
}
|
||||
|
||||
public decimal X1 { get; }
|
||||
public decimal Y1 { get; }
|
||||
public decimal X2 { get; }
|
||||
public decimal Y2 { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
@@ -26,7 +23,7 @@ namespace Umbraco.Core.Models
|
||||
/// <returns>
|
||||
/// A list of 5 different sized avatar URLs
|
||||
/// </returns>
|
||||
public static string[] GetUserAvatarUrls(this IUser user, IAppCache cache, IMediaFileSystem mediaFileSystem)
|
||||
public static string[] GetUserAvatarUrls(this IUser user, IAppCache cache, IMediaFileSystem mediaFileSystem, IImageUrlGenerator imageUrlGenerator)
|
||||
{
|
||||
// If FIPS is required, never check the Gravatar service as it only supports MD5 hashing.
|
||||
// Unfortunately, if the FIPS setting is enabled on Windows, using MD5 will throw an exception
|
||||
@@ -80,11 +77,11 @@ namespace Umbraco.Core.Models
|
||||
var avatarUrl = mediaFileSystem.GetUrl(user.Avatar);
|
||||
return new[]
|
||||
{
|
||||
avatarUrl + "?width=30&height=30&mode=crop",
|
||||
avatarUrl + "?width=60&height=60&mode=crop",
|
||||
avatarUrl + "?width=90&height=90&mode=crop",
|
||||
avatarUrl + "?width=150&height=150&mode=crop",
|
||||
avatarUrl + "?width=300&height=300&mode=crop"
|
||||
imageUrlGenerator.GetImageUrl(new ImageUrlGenerationOptions(avatarUrl) { ImageCropMode = "crop", Width = 30, Height = 30 }),
|
||||
imageUrlGenerator.GetImageUrl(new ImageUrlGenerationOptions(avatarUrl) { ImageCropMode = "crop", Width = 60, Height = 60 }),
|
||||
imageUrlGenerator.GetImageUrl(new ImageUrlGenerationOptions(avatarUrl) { ImageCropMode = "crop", Width = 90, Height = 90 }),
|
||||
imageUrlGenerator.GetImageUrl(new ImageUrlGenerationOptions(avatarUrl) { ImageCropMode = "crop", Width = 150, Height = 150 }),
|
||||
imageUrlGenerator.GetImageUrl(new ImageUrlGenerationOptions(avatarUrl) { ImageCropMode = "crop", Width = 300, Height = 300 })
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -77,7 +77,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
public IEnumerable<IAuditItem> Get(AuditType type, IQuery<IAuditItem> query)
|
||||
{
|
||||
var sqlClause = GetBaseQuery(false)
|
||||
.Where<LogDto>(x => x.Header == type.ToString());
|
||||
.Where("(logHeader=@0)", type.ToString());
|
||||
|
||||
var translator = new SqlTranslator<IAuditItem>(sqlClause, query);
|
||||
var sql = translator.Translate();
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Serialization;
|
||||
using Umbraco.Core.Strings;
|
||||
|
||||
@@ -59,38 +58,28 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
: Crops.FirstOrDefault(x => x.Alias.InvariantEquals(alias));
|
||||
}
|
||||
|
||||
public void AppendCropBaseUrl(StringBuilder url, ImageCropperCrop crop, bool defaultCrop, bool preferFocalPoint)
|
||||
public ImageUrlGenerationOptions GetCropBaseOptions(string url, ImageCropperCrop crop, bool defaultCrop, bool preferFocalPoint)
|
||||
{
|
||||
if (preferFocalPoint && HasFocalPoint()
|
||||
|| crop != null && crop.Coordinates == null && HasFocalPoint()
|
||||
|| defaultCrop && HasFocalPoint())
|
||||
{
|
||||
url.Append("?center=");
|
||||
url.Append(FocalPoint.Top.ToString(CultureInfo.InvariantCulture));
|
||||
url.Append(",");
|
||||
url.Append(FocalPoint.Left.ToString(CultureInfo.InvariantCulture));
|
||||
url.Append("&mode=crop");
|
||||
return new ImageUrlGenerationOptions(url) { FocalPoint = new ImageUrlGenerationOptions.FocalPointPosition(FocalPoint.Top, FocalPoint.Left) };
|
||||
}
|
||||
else if (crop != null && crop.Coordinates != null && preferFocalPoint == false)
|
||||
{
|
||||
url.Append("?crop=");
|
||||
url.Append(crop.Coordinates.X1.ToString(CultureInfo.InvariantCulture)).Append(",");
|
||||
url.Append(crop.Coordinates.Y1.ToString(CultureInfo.InvariantCulture)).Append(",");
|
||||
url.Append(crop.Coordinates.X2.ToString(CultureInfo.InvariantCulture)).Append(",");
|
||||
url.Append(crop.Coordinates.Y2.ToString(CultureInfo.InvariantCulture));
|
||||
url.Append("&cropmode=percentage");
|
||||
return new ImageUrlGenerationOptions(url) { Crop = new ImageUrlGenerationOptions.CropCoordinates(crop.Coordinates.X1, crop.Coordinates.Y1, crop.Coordinates.X2, crop.Coordinates.Y2) };
|
||||
}
|
||||
else
|
||||
{
|
||||
url.Append("?anchor=center");
|
||||
url.Append("&mode=crop");
|
||||
return new ImageUrlGenerationOptions(url) { DefaultCrop = true };
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value image url for a specified crop.
|
||||
/// </summary>
|
||||
public string GetCropUrl(string alias, bool useCropDimensions = true, bool useFocalPoint = false, string cacheBusterValue = null)
|
||||
public string GetCropUrl(string alias, IImageUrlGenerator imageUrlGenerator, bool useCropDimensions = true, bool useFocalPoint = false, string cacheBusterValue = null)
|
||||
{
|
||||
var crop = GetCrop(alias);
|
||||
|
||||
@@ -98,38 +87,31 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
if (crop == null && !string.IsNullOrWhiteSpace(alias))
|
||||
return null;
|
||||
|
||||
var url = new StringBuilder();
|
||||
|
||||
AppendCropBaseUrl(url, crop, string.IsNullOrWhiteSpace(alias), useFocalPoint);
|
||||
var options = GetCropBaseOptions(string.Empty, crop, string.IsNullOrWhiteSpace(alias), useFocalPoint);
|
||||
|
||||
if (crop != null && useCropDimensions)
|
||||
{
|
||||
url.Append("&width=").Append(crop.Width);
|
||||
url.Append("&height=").Append(crop.Height);
|
||||
options.Width = crop.Width;
|
||||
options.Height = crop.Height;
|
||||
}
|
||||
|
||||
if (cacheBusterValue != null)
|
||||
url.Append("&rnd=").Append(cacheBusterValue);
|
||||
options.CacheBusterValue = cacheBusterValue;
|
||||
|
||||
return url.ToString();
|
||||
return imageUrlGenerator.GetImageUrl(options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value image url for a specific width and height.
|
||||
/// </summary>
|
||||
public string GetCropUrl(int width, int height, bool useFocalPoint = false, string cacheBusterValue = null)
|
||||
public string GetCropUrl(int width, int height, IImageUrlGenerator imageUrlGenerator, bool useFocalPoint = false, string cacheBusterValue = null)
|
||||
{
|
||||
var url = new StringBuilder();
|
||||
var options = GetCropBaseOptions(string.Empty, null, true, useFocalPoint);
|
||||
|
||||
AppendCropBaseUrl(url, null, true, useFocalPoint);
|
||||
options.Width = width;
|
||||
options.Height = height;
|
||||
options.CacheBusterValue = cacheBusterValue;
|
||||
|
||||
url.Append("&width=").Append(width);
|
||||
url.Append("&height=").Append(height);
|
||||
|
||||
if (cacheBusterValue != null)
|
||||
url.Append("&rnd=").Append(cacheBusterValue);
|
||||
|
||||
return url.ToString();
|
||||
return imageUrlGenerator.GetImageUrl(options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -142,7 +142,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
if (pageIndex < 0) throw new ArgumentOutOfRangeException(nameof(pageIndex));
|
||||
if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize));
|
||||
|
||||
if (userId < 0)
|
||||
if (userId < Constants.Security.SuperUserId)
|
||||
{
|
||||
totalRecords = 0;
|
||||
return Enumerable.Empty<IAuditItem>();
|
||||
|
||||
232
src/Umbraco.Tests/Models/ImageProcessorImageUrlGeneratorTest.cs
Normal file
232
src/Umbraco.Tests/Models/ImageProcessorImageUrlGeneratorTest.cs
Normal file
@@ -0,0 +1,232 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.PropertyEditors.ValueConverters;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Tests.Components;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.PropertyEditors;
|
||||
using System.Text;
|
||||
|
||||
namespace Umbraco.Tests.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class ImageProcessorImageUrlGeneratorTest
|
||||
{
|
||||
private const string MediaPath = "/media/1005/img_0671.jpg";
|
||||
private static readonly ImageUrlGenerationOptions.CropCoordinates Crop = new ImageUrlGenerationOptions.CropCoordinates(0.58729977382575338m, 0.055768992440203169m, 0m, 0.32457553600198386m);
|
||||
private static readonly ImageUrlGenerationOptions.FocalPointPosition Focus1 = new ImageUrlGenerationOptions.FocalPointPosition(0.80827067669172936m, 0.96m);
|
||||
private static readonly ImageUrlGenerationOptions.FocalPointPosition Focus2 = new ImageUrlGenerationOptions.FocalPointPosition(0.41m, 0.4275m);
|
||||
private static readonly ImageProcessorImageUrlGenerator Generator = new ImageProcessorImageUrlGenerator();
|
||||
|
||||
[Test]
|
||||
public void GetCropUrl_CropAliasTest()
|
||||
{
|
||||
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { Crop = Crop, Width = 100, Height = 100 });
|
||||
Assert.AreEqual(MediaPath + "?crop=0.58729977382575338,0.055768992440203169,0,0.32457553600198386&cropmode=percentage&width=100&height=100", urlString);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetCropUrl_WidthHeightTest()
|
||||
{
|
||||
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { FocalPoint = Focus1, Width = 200, Height = 300 });
|
||||
Assert.AreEqual(MediaPath + "?center=0.80827067669172936,0.96&mode=crop&width=200&height=300", urlString);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetCropUrl_FocalPointTest()
|
||||
{
|
||||
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { FocalPoint = Focus1, Width = 100, Height = 100 });
|
||||
Assert.AreEqual(MediaPath + "?center=0.80827067669172936,0.96&mode=crop&width=100&height=100", urlString);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetCropUrlFurtherOptionsTest()
|
||||
{
|
||||
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { FocalPoint = Focus1, Width = 200, Height = 300, FurtherOptions = "&filter=comic&roundedcorners=radius-26|bgcolor-fff" });
|
||||
Assert.AreEqual(MediaPath + "?center=0.80827067669172936,0.96&mode=crop&width=200&height=300&filter=comic&roundedcorners=radius-26|bgcolor-fff", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test that if a crop alias has been specified that doesn't exist the method returns null
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetCropUrlNullTest()
|
||||
{
|
||||
var urlString = Generator.GetImageUrl(null);
|
||||
Assert.AreEqual(null, urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test that if a crop alias has been specified that doesn't exist the method returns null
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetCropUrlEmptyTest()
|
||||
{
|
||||
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(null));
|
||||
Assert.AreEqual("?mode=crop", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test the GetCropUrl method on the ImageCropDataSet Model
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetBaseCropUrlFromModelTest()
|
||||
{
|
||||
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(null) { Crop = Crop, Width = 100, Height = 100 });
|
||||
Assert.AreEqual("?crop=0.58729977382575338,0.055768992440203169,0,0.32457553600198386&cropmode=percentage&width=100&height=100", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test the height ratio mode with predefined crop dimensions
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetCropUrl_CropAliasHeightRatioModeTest()
|
||||
{
|
||||
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { Crop = Crop, Width = 100, HeightRatio = 1 });
|
||||
Assert.AreEqual(MediaPath + "?crop=0.58729977382575338,0.055768992440203169,0,0.32457553600198386&cropmode=percentage&heightratio=1&width=100", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test the height ratio mode with manual width/height dimensions
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetCropUrl_WidthHeightRatioModeTest()
|
||||
{
|
||||
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { FocalPoint = Focus1, Width = 300, HeightRatio = 0.5m });
|
||||
Assert.AreEqual(MediaPath + "?center=0.80827067669172936,0.96&mode=crop&heightratio=0.5&width=300", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test the height ratio mode with width/height dimensions
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetCropUrl_HeightWidthRatioModeTest()
|
||||
{
|
||||
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { FocalPoint = Focus1, Height = 150, WidthRatio = 2 });
|
||||
Assert.AreEqual(MediaPath + "?center=0.80827067669172936,0.96&mode=crop&widthratio=2&height=150", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test that if Crop mode is specified as anything other than Crop the image doesn't use the crop
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetCropUrl_SpecifiedCropModeTest()
|
||||
{
|
||||
var urlStringMin = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { ImageCropMode = "Min", Width = 300, Height = 150 });
|
||||
var urlStringBoxPad = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { ImageCropMode = "BoxPad", Width = 300, Height = 150 });
|
||||
var urlStringPad = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { ImageCropMode = "Pad", Width = 300, Height = 150 });
|
||||
var urlStringMax = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { ImageCropMode = "Max", Width = 300, Height = 150 });
|
||||
var urlStringStretch = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { ImageCropMode = "Stretch", Width = 300, Height = 150 });
|
||||
|
||||
Assert.AreEqual(MediaPath + "?mode=min&width=300&height=150", urlStringMin);
|
||||
Assert.AreEqual(MediaPath + "?mode=boxpad&width=300&height=150", urlStringBoxPad);
|
||||
Assert.AreEqual(MediaPath + "?mode=pad&width=300&height=150", urlStringPad);
|
||||
Assert.AreEqual(MediaPath + "?mode=max&width=300&height=150", urlStringMax);
|
||||
Assert.AreEqual(MediaPath + "?mode=stretch&width=300&height=150", urlStringStretch);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test for upload property type
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetCropUrl_UploadTypeTest()
|
||||
{
|
||||
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { ImageCropMode = "Crop", ImageCropAnchor = "Center", Width = 100, Height = 270 });
|
||||
Assert.AreEqual(MediaPath + "?mode=crop&anchor=center&width=100&height=270", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test for preferFocalPoint when focal point is centered
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetCropUrl_PreferFocalPointCenter()
|
||||
{
|
||||
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { DefaultCrop = true, Width = 300, Height = 150 });
|
||||
Assert.AreEqual(MediaPath + "?anchor=center&mode=crop&width=300&height=150", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test to check if height ratio is returned for a predefined crop without coordinates and focal point in centre when a width parameter is passed
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetCropUrl_PreDefinedCropNoCoordinatesWithWidth()
|
||||
{
|
||||
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { DefaultCrop = true, Width = 200, HeightRatio = 0.5962962962962962962962962963m });
|
||||
Assert.AreEqual(MediaPath + "?anchor=center&mode=crop&heightratio=0.5962962962962962962962962963&width=200", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test to check if height ratio is returned for a predefined crop without coordinates and focal point is custom when a width parameter is passed
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetCropUrl_PreDefinedCropNoCoordinatesWithWidthAndFocalPoint()
|
||||
{
|
||||
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { FocalPoint = Focus2, Width = 200, HeightRatio = 0.5962962962962962962962962963m });
|
||||
Assert.AreEqual(MediaPath + "?center=0.41,0.4275&mode=crop&heightratio=0.5962962962962962962962962963&width=200", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test to check if crop ratio is ignored if useCropDimensions is true
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetCropUrl_PreDefinedCropNoCoordinatesWithWidthAndFocalPointIgnore()
|
||||
{
|
||||
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { FocalPoint = Focus2, Width = 270, Height = 161 });
|
||||
Assert.AreEqual(MediaPath + "?center=0.41,0.4275&mode=crop&width=270&height=161", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test to check if width ratio is returned for a predefined crop without coordinates and focal point in centre when a height parameter is passed
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetCropUrl_PreDefinedCropNoCoordinatesWithHeight()
|
||||
{
|
||||
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { DefaultCrop = true, Height = 200, WidthRatio = 1.6770186335403726708074534161m });
|
||||
Assert.AreEqual(MediaPath + "?anchor=center&mode=crop&widthratio=1.6770186335403726708074534161&height=200", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test to check result when only a width parameter is passed, effectivly a resize only
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetCropUrl_WidthOnlyParameter()
|
||||
{
|
||||
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { DefaultCrop = true, Width = 200 });
|
||||
Assert.AreEqual(MediaPath + "?anchor=center&mode=crop&width=200", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test to check result when only a height parameter is passed, effectivly a resize only
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetCropUrl_HeightOnlyParameter()
|
||||
{
|
||||
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { DefaultCrop = true, Height = 200 });
|
||||
Assert.AreEqual(MediaPath + "?anchor=center&mode=crop&height=200", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test to check result when using a background color with padding
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GetCropUrl_BackgroundColorParameter()
|
||||
{
|
||||
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { ImageCropMode = "Pad", Width = 400, Height = 400, FurtherOptions = "&bgcolor=fff" });
|
||||
Assert.AreEqual(MediaPath + "?mode=pad&width=400&height=400&bgcolor=fff", urlString);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.IO;
|
||||
@@ -21,7 +20,9 @@ using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.PropertyEditors;
|
||||
using System.Text;
|
||||
using Current = Umbraco.Web.Composing.Current;
|
||||
using Umbraco.Core.Cache;
|
||||
|
||||
namespace Umbraco.Tests.PropertyEditors
|
||||
{
|
||||
@@ -113,8 +114,8 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
[Test]
|
||||
public void GetCropUrl_CropAliasTest()
|
||||
{
|
||||
var urlString = MediaPath.GetCropUrl(imageCropperValue: CropperJson1, cropAlias: "Thumb", useCropDimensions: true);
|
||||
Assert.AreEqual(MediaPath + "?crop=0.58729977382575338,0.055768992440203169,0,0.32457553600198386&cropmode=percentage&width=100&height=100", urlString);
|
||||
var urlString = MediaPath.GetCropUrl(new TestImageUrlGenerator(), imageCropperValue: CropperJson1, cropAlias: "Thumb", useCropDimensions: true);
|
||||
Assert.AreEqual(MediaPath + "?c=0.58729977382575338,0.055768992440203169,0,0.32457553600198386&w=100&h=100", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -123,29 +124,29 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
[Test]
|
||||
public void GetCropUrl_CropAliasIgnoreWidthHeightTest()
|
||||
{
|
||||
var urlString = MediaPath.GetCropUrl(imageCropperValue: CropperJson1, cropAlias: "Thumb", useCropDimensions: true, width: 50, height: 50);
|
||||
Assert.AreEqual(MediaPath + "?crop=0.58729977382575338,0.055768992440203169,0,0.32457553600198386&cropmode=percentage&width=100&height=100", urlString);
|
||||
var urlString = MediaPath.GetCropUrl(new TestImageUrlGenerator(), imageCropperValue: CropperJson1, cropAlias: "Thumb", useCropDimensions: true, width: 50, height: 50);
|
||||
Assert.AreEqual(MediaPath + "?c=0.58729977382575338,0.055768992440203169,0,0.32457553600198386&w=100&h=100", urlString);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetCropUrl_WidthHeightTest()
|
||||
{
|
||||
var urlString = MediaPath.GetCropUrl(imageCropperValue: CropperJson1, width: 200, height: 300);
|
||||
Assert.AreEqual(MediaPath + "?center=0.80827067669172936,0.96&mode=crop&width=200&height=300", urlString);
|
||||
var urlString = MediaPath.GetCropUrl(new TestImageUrlGenerator(), imageCropperValue: CropperJson1, width: 200, height: 300);
|
||||
Assert.AreEqual(MediaPath + "?f=0.80827067669172936x0.96&w=200&h=300", urlString);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetCropUrl_FocalPointTest()
|
||||
{
|
||||
var urlString = MediaPath.GetCropUrl(imageCropperValue: CropperJson1, cropAlias: "thumb", preferFocalPoint: true, useCropDimensions: true);
|
||||
Assert.AreEqual(MediaPath + "?center=0.80827067669172936,0.96&mode=crop&width=100&height=100", urlString);
|
||||
var urlString = MediaPath.GetCropUrl(new TestImageUrlGenerator(), imageCropperValue: CropperJson1, cropAlias: "thumb", preferFocalPoint: true, useCropDimensions: true);
|
||||
Assert.AreEqual(MediaPath + "?f=0.80827067669172936x0.96&w=100&h=100", urlString);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetCropUrlFurtherOptionsTest()
|
||||
{
|
||||
var urlString = MediaPath.GetCropUrl(imageCropperValue: CropperJson1, width: 200, height: 300, furtherOptions: "&filter=comic&roundedcorners=radius-26|bgcolor-fff");
|
||||
Assert.AreEqual(MediaPath + "?center=0.80827067669172936,0.96&mode=crop&width=200&height=300&filter=comic&roundedcorners=radius-26|bgcolor-fff", urlString);
|
||||
var urlString = MediaPath.GetCropUrl(new TestImageUrlGenerator(), imageCropperValue: CropperJson1, width: 200, height: 300, furtherOptions: "&filter=comic&roundedcorners=radius-26|bgcolor-fff");
|
||||
Assert.AreEqual(MediaPath + "?f=0.80827067669172936x0.96&w=200&h=300&filter=comic&roundedcorners=radius-26|bgcolor-fff", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -154,7 +155,7 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
[Test]
|
||||
public void GetCropUrlNullTest()
|
||||
{
|
||||
var urlString = MediaPath.GetCropUrl(imageCropperValue: CropperJson1, cropAlias: "Banner", useCropDimensions: true);
|
||||
var urlString = MediaPath.GetCropUrl(new TestImageUrlGenerator(), imageCropperValue: CropperJson1, cropAlias: "Banner", useCropDimensions: true);
|
||||
Assert.AreEqual(null, urlString);
|
||||
}
|
||||
|
||||
@@ -165,8 +166,8 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
public void GetBaseCropUrlFromModelTest()
|
||||
{
|
||||
var cropDataSet = CropperJson1.DeserializeImageCropperValue();
|
||||
var urlString = cropDataSet.GetCropUrl("thumb");
|
||||
Assert.AreEqual("?crop=0.58729977382575338,0.055768992440203169,0,0.32457553600198386&cropmode=percentage&width=100&height=100", urlString);
|
||||
var urlString = cropDataSet.GetCropUrl("thumb", new TestImageUrlGenerator());
|
||||
Assert.AreEqual("?c=0.58729977382575338,0.055768992440203169,0,0.32457553600198386&w=100&h=100", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -175,8 +176,8 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
[Test]
|
||||
public void GetCropUrl_CropAliasHeightRatioModeTest()
|
||||
{
|
||||
var urlString = MediaPath.GetCropUrl(imageCropperValue: CropperJson1, cropAlias: "Thumb", useCropDimensions: true, ratioMode:ImageCropRatioMode.Height);
|
||||
Assert.AreEqual(MediaPath + "?crop=0.58729977382575338,0.055768992440203169,0,0.32457553600198386&cropmode=percentage&width=100&heightratio=1", urlString);
|
||||
var urlString = MediaPath.GetCropUrl(new TestImageUrlGenerator(), imageCropperValue: CropperJson1, cropAlias: "Thumb", useCropDimensions: true, ratioMode:ImageCropRatioMode.Height);
|
||||
Assert.AreEqual(MediaPath + "?c=0.58729977382575338,0.055768992440203169,0,0.32457553600198386&hr=1&w=100", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -185,8 +186,8 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
[Test]
|
||||
public void GetCropUrl_WidthHeightRatioModeTest()
|
||||
{
|
||||
var urlString = MediaPath.GetCropUrl(imageCropperValue: CropperJson1, width: 300, height: 150, ratioMode:ImageCropRatioMode.Height);
|
||||
Assert.AreEqual(MediaPath + "?center=0.80827067669172936,0.96&mode=crop&width=300&heightratio=0.5", urlString);
|
||||
var urlString = MediaPath.GetCropUrl(new TestImageUrlGenerator(), imageCropperValue: CropperJson1, width: 300, height: 150, ratioMode:ImageCropRatioMode.Height);
|
||||
Assert.AreEqual(MediaPath + "?f=0.80827067669172936x0.96&hr=0.5&w=300", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -195,8 +196,8 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
[Test]
|
||||
public void GetCropUrl_HeightWidthRatioModeTest()
|
||||
{
|
||||
var urlString = MediaPath.GetCropUrl(imageCropperValue: CropperJson1, width: 300, height: 150, ratioMode: ImageCropRatioMode.Width);
|
||||
Assert.AreEqual(MediaPath + "?center=0.80827067669172936,0.96&mode=crop&height=150&widthratio=2", urlString);
|
||||
var urlString = MediaPath.GetCropUrl(new TestImageUrlGenerator(), imageCropperValue: CropperJson1, width: 300, height: 150, ratioMode: ImageCropRatioMode.Width);
|
||||
Assert.AreEqual(MediaPath + "?f=0.80827067669172936x0.96&wr=2&h=150", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -205,17 +206,17 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
[Test]
|
||||
public void GetCropUrl_SpecifiedCropModeTest()
|
||||
{
|
||||
var urlStringMin = MediaPath.GetCropUrl(imageCropperValue: CropperJson1, width: 300, height: 150, imageCropMode: ImageCropMode.Min);
|
||||
var urlStringBoxPad = MediaPath.GetCropUrl(imageCropperValue: CropperJson1, width: 300, height: 150, imageCropMode: ImageCropMode.BoxPad);
|
||||
var urlStringPad = MediaPath.GetCropUrl(imageCropperValue: CropperJson1, width: 300, height: 150, imageCropMode: ImageCropMode.Pad);
|
||||
var urlString = MediaPath.GetCropUrl(imageCropperValue: CropperJson1, width: 300, height: 150, imageCropMode:ImageCropMode.Max);
|
||||
var urlStringStretch = MediaPath.GetCropUrl(imageCropperValue: CropperJson1, width: 300, height: 150, imageCropMode: ImageCropMode.Stretch);
|
||||
var urlStringMin = MediaPath.GetCropUrl(new TestImageUrlGenerator(), imageCropperValue: CropperJson1, width: 300, height: 150, imageCropMode: ImageCropMode.Min);
|
||||
var urlStringBoxPad = MediaPath.GetCropUrl(new TestImageUrlGenerator(), imageCropperValue: CropperJson1, width: 300, height: 150, imageCropMode: ImageCropMode.BoxPad);
|
||||
var urlStringPad = MediaPath.GetCropUrl(new TestImageUrlGenerator(), imageCropperValue: CropperJson1, width: 300, height: 150, imageCropMode: ImageCropMode.Pad);
|
||||
var urlString = MediaPath.GetCropUrl(new TestImageUrlGenerator(), imageCropperValue: CropperJson1, width: 300, height: 150, imageCropMode:ImageCropMode.Max);
|
||||
var urlStringStretch = MediaPath.GetCropUrl(new TestImageUrlGenerator(), imageCropperValue: CropperJson1, width: 300, height: 150, imageCropMode: ImageCropMode.Stretch);
|
||||
|
||||
Assert.AreEqual(MediaPath + "?mode=min&width=300&height=150", urlStringMin);
|
||||
Assert.AreEqual(MediaPath + "?mode=boxpad&width=300&height=150", urlStringBoxPad);
|
||||
Assert.AreEqual(MediaPath + "?mode=pad&width=300&height=150", urlStringPad);
|
||||
Assert.AreEqual(MediaPath + "?mode=max&width=300&height=150", urlString);
|
||||
Assert.AreEqual(MediaPath + "?mode=stretch&width=300&height=150", urlStringStretch);
|
||||
Assert.AreEqual(MediaPath + "?m=min&w=300&h=150", urlStringMin);
|
||||
Assert.AreEqual(MediaPath + "?m=boxpad&w=300&h=150", urlStringBoxPad);
|
||||
Assert.AreEqual(MediaPath + "?m=pad&w=300&h=150", urlStringPad);
|
||||
Assert.AreEqual(MediaPath + "?m=max&w=300&h=150", urlString);
|
||||
Assert.AreEqual(MediaPath + "?m=stretch&w=300&h=150", urlStringStretch);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -224,8 +225,8 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
[Test]
|
||||
public void GetCropUrl_UploadTypeTest()
|
||||
{
|
||||
var urlString = MediaPath.GetCropUrl(width: 100, height: 270, imageCropMode: ImageCropMode.Crop, imageCropAnchor: ImageCropAnchor.Center);
|
||||
Assert.AreEqual(MediaPath + "?mode=crop&anchor=center&width=100&height=270", urlString);
|
||||
var urlString = MediaPath.GetCropUrl(new TestImageUrlGenerator(), width: 100, height: 270, imageCropMode: ImageCropMode.Crop, imageCropAnchor: ImageCropAnchor.Center);
|
||||
Assert.AreEqual(MediaPath + "?m=crop&a=center&w=100&h=270", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -236,8 +237,8 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
{
|
||||
const string cropperJson = "{\"focalPoint\": {\"left\": 0.5,\"top\": 0.5},\"src\": \"/media/1005/img_0671.jpg\",\"crops\": [{\"alias\":\"thumb\",\"width\": 100,\"height\": 100,\"coordinates\": {\"x1\": 0.58729977382575338,\"y1\": 0.055768992440203169,\"x2\": 0,\"y2\": 0.32457553600198386}}]}";
|
||||
|
||||
var urlString = MediaPath.GetCropUrl(imageCropperValue: cropperJson, width: 300, height: 150, preferFocalPoint:true);
|
||||
Assert.AreEqual(MediaPath + "?anchor=center&mode=crop&width=300&height=150", urlString);
|
||||
var urlString = MediaPath.GetCropUrl(new TestImageUrlGenerator(), imageCropperValue: cropperJson, width: 300, height: 150, preferFocalPoint:true);
|
||||
Assert.AreEqual(MediaPath + "?m=defaultcrop&w=300&h=150", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -248,8 +249,8 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
{
|
||||
const string cropperJson = "{\"focalPoint\": {\"left\": 0.5,\"top\": 0.5},\"src\": \"/media/1005/img_0671.jpg\",\"crops\": [{\"alias\": \"home\",\"width\": 270,\"height\": 161}]}";
|
||||
|
||||
var urlString = MediaPath.GetCropUrl(imageCropperValue: cropperJson, cropAlias: "home", width: 200);
|
||||
Assert.AreEqual(MediaPath + "?anchor=center&mode=crop&heightratio=0.5962962962962962962962962963&width=200", urlString);
|
||||
var urlString = MediaPath.GetCropUrl(new TestImageUrlGenerator(), imageCropperValue: cropperJson, cropAlias: "home", width: 200);
|
||||
Assert.AreEqual(MediaPath + "?m=defaultcrop&hr=0.5962962962962962962962962963&w=200", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -260,8 +261,8 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
{
|
||||
const string cropperJson = "{\"focalPoint\": {\"left\": 0.4275,\"top\": 0.41},\"src\": \"/media/1005/img_0671.jpg\",\"crops\": [{\"alias\": \"home\",\"width\": 270,\"height\": 161}]}";
|
||||
|
||||
var urlString = MediaPath.GetCropUrl(imageCropperValue: cropperJson, cropAlias: "home", width: 200);
|
||||
Assert.AreEqual(MediaPath + "?center=0.41,0.4275&mode=crop&heightratio=0.5962962962962962962962962963&width=200", urlString);
|
||||
var urlString = MediaPath.GetCropUrl(new TestImageUrlGenerator(), imageCropperValue: cropperJson, cropAlias: "home", width: 200);
|
||||
Assert.AreEqual(MediaPath + "?f=0.41x0.4275&hr=0.5962962962962962962962962963&w=200", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -272,8 +273,8 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
{
|
||||
const string cropperJson = "{\"focalPoint\": {\"left\": 0.4275,\"top\": 0.41},\"src\": \"/media/1005/img_0671.jpg\",\"crops\": [{\"alias\": \"home\",\"width\": 270,\"height\": 161}]}";
|
||||
|
||||
var urlString = MediaPath.GetCropUrl(imageCropperValue: cropperJson, cropAlias: "home", width: 200, useCropDimensions: true);
|
||||
Assert.AreEqual(MediaPath + "?center=0.41,0.4275&mode=crop&width=270&height=161", urlString);
|
||||
var urlString = MediaPath.GetCropUrl(new TestImageUrlGenerator(), imageCropperValue: cropperJson, cropAlias: "home", width: 200, useCropDimensions: true);
|
||||
Assert.AreEqual(MediaPath + "?f=0.41x0.4275&w=270&h=161", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -284,8 +285,8 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
{
|
||||
const string cropperJson = "{\"focalPoint\": {\"left\": 0.5,\"top\": 0.5},\"src\": \"/media/1005/img_0671.jpg\",\"crops\": [{\"alias\": \"home\",\"width\": 270,\"height\": 161}]}";
|
||||
|
||||
var urlString = MediaPath.GetCropUrl(imageCropperValue: cropperJson, cropAlias: "home", height: 200);
|
||||
Assert.AreEqual(MediaPath + "?anchor=center&mode=crop&widthratio=1.6770186335403726708074534161&height=200", urlString);
|
||||
var urlString = MediaPath.GetCropUrl(new TestImageUrlGenerator(), imageCropperValue: cropperJson, cropAlias: "home", height: 200);
|
||||
Assert.AreEqual(MediaPath + "?m=defaultcrop&wr=1.6770186335403726708074534161&h=200", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -296,8 +297,8 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
{
|
||||
const string cropperJson = "{\"focalPoint\": {\"left\": 0.5,\"top\": 0.5},\"src\": \"/media/1005/img_0671.jpg\",\"crops\": [{\"alias\": \"home\",\"width\": 270,\"height\": 161}]}";
|
||||
|
||||
var urlString = MediaPath.GetCropUrl(imageCropperValue: cropperJson, width: 200);
|
||||
Assert.AreEqual(MediaPath + "?anchor=center&mode=crop&width=200", urlString);
|
||||
var urlString = MediaPath.GetCropUrl(new TestImageUrlGenerator(), imageCropperValue: cropperJson, width: 200);
|
||||
Assert.AreEqual(MediaPath + "?m=defaultcrop&w=200", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -308,8 +309,8 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
{
|
||||
const string cropperJson = "{\"focalPoint\": {\"left\": 0.5,\"top\": 0.5},\"src\": \"/media/1005/img_0671.jpg\",\"crops\": [{\"alias\": \"home\",\"width\": 270,\"height\": 161}]}";
|
||||
|
||||
var urlString = MediaPath.GetCropUrl(imageCropperValue: cropperJson, height: 200);
|
||||
Assert.AreEqual(MediaPath + "?anchor=center&mode=crop&height=200", urlString);
|
||||
var urlString = MediaPath.GetCropUrl(new TestImageUrlGenerator(), imageCropperValue: cropperJson, height: 200);
|
||||
Assert.AreEqual(MediaPath + "?m=defaultcrop&h=200", urlString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -320,8 +321,55 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
{
|
||||
var cropperJson = "{\"focalPoint\": {\"left\": 0.5,\"top\": 0.5},\"src\": \"" + MediaPath + "\",\"crops\": [{\"alias\": \"home\",\"width\": 270,\"height\": 161}]}";
|
||||
|
||||
var urlString = MediaPath.GetCropUrl(400, 400, cropperJson, imageCropMode: ImageCropMode.Pad, furtherOptions: "&bgcolor=fff");
|
||||
Assert.AreEqual(MediaPath + "?mode=pad&width=400&height=400&bgcolor=fff", urlString);
|
||||
var urlString = MediaPath.GetCropUrl(new TestImageUrlGenerator(), 400, 400, cropperJson, imageCropMode: ImageCropMode.Pad, furtherOptions: "&bgcolor=fff");
|
||||
Assert.AreEqual(MediaPath + "?m=pad&w=400&h=400&bgcolor=fff", urlString);
|
||||
}
|
||||
|
||||
internal class TestImageUrlGenerator : IImageUrlGenerator
|
||||
{
|
||||
public string GetImageUrl(ImageUrlGenerationOptions options)
|
||||
{
|
||||
var imageProcessorUrl = new StringBuilder(options.ImageUrl ?? string.Empty);
|
||||
|
||||
if (options.FocalPoint != null)
|
||||
{
|
||||
imageProcessorUrl.Append("?f=");
|
||||
imageProcessorUrl.Append(options.FocalPoint.Top.ToString(CultureInfo.InvariantCulture));
|
||||
imageProcessorUrl.Append("x");
|
||||
imageProcessorUrl.Append(options.FocalPoint.Left.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
else if (options.Crop != null)
|
||||
{
|
||||
imageProcessorUrl.Append("?c=");
|
||||
imageProcessorUrl.Append(options.Crop.X1.ToString(CultureInfo.InvariantCulture)).Append(",");
|
||||
imageProcessorUrl.Append(options.Crop.Y1.ToString(CultureInfo.InvariantCulture)).Append(",");
|
||||
imageProcessorUrl.Append(options.Crop.X2.ToString(CultureInfo.InvariantCulture)).Append(",");
|
||||
imageProcessorUrl.Append(options.Crop.Y2.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
else if (options.DefaultCrop)
|
||||
{
|
||||
imageProcessorUrl.Append("?m=defaultcrop");
|
||||
}
|
||||
else
|
||||
{
|
||||
imageProcessorUrl.Append("?m=" + options.ImageCropMode.ToString().ToLower());
|
||||
if (options.ImageCropAnchor != null)imageProcessorUrl.Append("&a=" + options.ImageCropAnchor.ToString().ToLower());
|
||||
}
|
||||
|
||||
var hasFormat = options.FurtherOptions != null && options.FurtherOptions.InvariantContains("&f=");
|
||||
if (options.Quality != null && hasFormat == false) imageProcessorUrl.Append("&q=" + options.Quality);
|
||||
if (options.HeightRatio != null) imageProcessorUrl.Append("&hr=" + options.HeightRatio.Value.ToString(CultureInfo.InvariantCulture));
|
||||
if (options.WidthRatio != null) imageProcessorUrl.Append("&wr=" + options.WidthRatio.Value.ToString(CultureInfo.InvariantCulture));
|
||||
if (options.Width != null) imageProcessorUrl.Append("&w=" + options.Width);
|
||||
if (options.Height != null) imageProcessorUrl.Append("&h=" + options.Height);
|
||||
if (options.UpScale == false) imageProcessorUrl.Append("&u=no");
|
||||
if (options.AnimationProcessMode != null) imageProcessorUrl.Append("&apm=" + options.AnimationProcessMode);
|
||||
if (options.FurtherOptions != null) imageProcessorUrl.Append(options.FurtherOptions);
|
||||
if (options.Quality != null && hasFormat) imageProcessorUrl.Append("&q=" + options.Quality);
|
||||
if (options.CacheBusterValue != null) imageProcessorUrl.Append("&r=").Append(options.CacheBusterValue);
|
||||
|
||||
return imageProcessorUrl.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Templates;
|
||||
using Umbraco.Web.Models;
|
||||
|
||||
namespace Umbraco.Tests.PublishedContent
|
||||
{
|
||||
@@ -60,7 +61,8 @@ namespace Umbraco.Tests.PublishedContent
|
||||
pastedImages,
|
||||
ShortStringHelper,
|
||||
IOHelper,
|
||||
LocalizedTextService)) { Id = 1 });
|
||||
LocalizedTextService,
|
||||
Mock.Of<IImageUrlGenerator>())) { Id = 1 });
|
||||
|
||||
|
||||
var publishedContentTypeFactory = new PublishedContentTypeFactory(Mock.Of<IPublishedModelFactory>(), converters, dataTypeService);
|
||||
|
||||
@@ -22,6 +22,7 @@ using Umbraco.Tests.Testing;
|
||||
using Umbraco.Web.Models.PublishedContent;
|
||||
using Umbraco.Web.PropertyEditors;
|
||||
using Umbraco.Web.Templates;
|
||||
using Umbraco.Web.Models;
|
||||
using Current = Umbraco.Web.Composing.Current;
|
||||
|
||||
namespace Umbraco.Tests.PublishedContent
|
||||
@@ -56,7 +57,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
var dataTypeService = new TestObjects.TestDataTypeService(
|
||||
new DataType(new VoidEditor(logger, Mock.Of<IDataTypeService>(), localizationService, LocalizedTextService, ShortStringHelper)) { Id = 1 },
|
||||
new DataType(new TrueFalsePropertyEditor(logger, Mock.Of<IDataTypeService>(), localizationService, IOHelper, ShortStringHelper, LocalizedTextService)) { Id = 1001 },
|
||||
new DataType(new RichTextPropertyEditor(logger, mediaService, contentTypeBaseServiceProvider, umbracoContextAccessor, Mock.Of<IDataTypeService>(), localizationService, imageSourceParser, linkParser, pastedImages, ShortStringHelper, IOHelper, LocalizedTextService)) { Id = 1002 },
|
||||
new DataType(new RichTextPropertyEditor(logger, mediaService, contentTypeBaseServiceProvider, umbracoContextAccessor, Mock.Of<IDataTypeService>(), localizationService, imageSourceParser, linkParser, pastedImages, ShortStringHelper, IOHelper, LocalizedTextService, Mock.Of<IImageUrlGenerator>())) { Id = 1002 },
|
||||
new DataType(new IntegerPropertyEditor(logger, Mock.Of<IDataTypeService>(), localizationService, ShortStringHelper, LocalizedTextService)) { Id = 1003 },
|
||||
new DataType(new TextboxPropertyEditor(logger, Mock.Of<IDataTypeService>(), localizationService, IOHelper, ShortStringHelper, LocalizedTextService)) { Id = 1004 },
|
||||
new DataType(new MediaPickerPropertyEditor(logger, Mock.Of<IDataTypeService>(), localizationService, IOHelper, ShortStringHelper, LocalizedTextService)) { Id = 1005 });
|
||||
|
||||
@@ -106,6 +106,7 @@ namespace Umbraco.Tests.Runtimes
|
||||
composition.Register<IDefaultCultureAccessor, TestDefaultCultureAccessor>(Lifetime.Singleton);
|
||||
composition.Register<ISiteDomainHelper>(_ => Mock.Of<ISiteDomainHelper>(), Lifetime.Singleton);
|
||||
composition.RegisterUnique(f => new DistributedCache(f.GetInstance<IServerMessenger>(), f.GetInstance<CacheRefresherCollection>()));
|
||||
composition.Register(_ => Mock.Of<IImageUrlGenerator>(), Lifetime.Singleton);
|
||||
composition.WithCollectionBuilder<UrlProviderCollectionBuilder>().Append<DefaultUrlProvider>();
|
||||
composition.RegisterUnique<IDistributedCacheBinder, DistributedCacheBinder>();
|
||||
composition.RegisterUnique<IExamineManager, ExamineManager>();
|
||||
|
||||
@@ -48,6 +48,7 @@ using FileSystems = Umbraco.Core.IO.FileSystems;
|
||||
using Umbraco.Web.Templates;
|
||||
using Umbraco.Web.PropertyEditors;
|
||||
using Umbraco.Core.Dictionary;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Identity;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Core.Services;
|
||||
@@ -304,6 +305,7 @@ namespace Umbraco.Tests.Testing
|
||||
var runtimeStateMock = new Mock<IRuntimeState>();
|
||||
runtimeStateMock.Setup(x => x.Level).Returns(RuntimeLevel.Run);
|
||||
Composition.RegisterUnique(f => runtimeStateMock.Object);
|
||||
Composition.Register(_ => Mock.Of<IImageUrlGenerator>());
|
||||
|
||||
// ah...
|
||||
Composition.WithCollectionBuilder<ActionCollectionBuilder>();
|
||||
|
||||
@@ -142,6 +142,7 @@
|
||||
<Compile Include="ModelsBuilder\UmbracoApplicationTests.cs" />
|
||||
<Compile Include="Models\ContentScheduleTests.cs" />
|
||||
<Compile Include="Models\CultureImpactTests.cs" />
|
||||
<Compile Include="Models\ImageProcessorImageUrlGeneratorTest.cs" />
|
||||
<Compile Include="Models\PathValidationTests.cs" />
|
||||
<Compile Include="Models\VariationTests.cs" />
|
||||
<Compile Include="Persistence\Mappers\MapperTestBase.cs" />
|
||||
|
||||
@@ -90,7 +90,8 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
ShortStringHelper,
|
||||
Factory.GetInstance<UmbracoMapper>(),
|
||||
Factory.GetInstance<IUmbracoSettingsSection>(),
|
||||
Factory.GetInstance<IIOHelper>()
|
||||
Factory.GetInstance<IIOHelper>(),
|
||||
Factory.GetInstance<IImageUrlGenerator>()
|
||||
);
|
||||
return usersController;
|
||||
}
|
||||
@@ -160,7 +161,8 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
ShortStringHelper,
|
||||
Factory.GetInstance<UmbracoMapper>(),
|
||||
Factory.GetInstance<IUmbracoSettingsSection>(),
|
||||
Factory.GetInstance<IIOHelper>()
|
||||
Factory.GetInstance<IIOHelper>(),
|
||||
Factory.GetInstance<IImageUrlGenerator>()
|
||||
);
|
||||
return usersController;
|
||||
}
|
||||
@@ -201,7 +203,8 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
ShortStringHelper,
|
||||
Factory.GetInstance<UmbracoMapper>(),
|
||||
Factory.GetInstance<IUmbracoSettingsSection>(),
|
||||
Factory.GetInstance<IIOHelper>()
|
||||
Factory.GetInstance<IIOHelper>(),
|
||||
Factory.GetInstance<IImageUrlGenerator>()
|
||||
);
|
||||
return usersController;
|
||||
}
|
||||
@@ -277,7 +280,8 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
ShortStringHelper,
|
||||
Factory.GetInstance<UmbracoMapper>(),
|
||||
Factory.GetInstance<IUmbracoSettingsSection>(),
|
||||
Factory.GetInstance<IIOHelper>()
|
||||
Factory.GetInstance<IIOHelper>(),
|
||||
Factory.GetInstance<IImageUrlGenerator>()
|
||||
);
|
||||
return usersController;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name umbraco.resources.imageUrlGeneratorResource
|
||||
* @function
|
||||
*
|
||||
* @description
|
||||
* Used by the various controllers to get an image URL formatted correctly for the current image URL generator
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function imageUrlGeneratorResource($http, umbRequestHelper) {
|
||||
|
||||
function getCropUrl(mediaPath, width, height, imageCropMode, animationProcessMode) {
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"imageUrlGeneratorApiBaseUrl",
|
||||
"GetCropUrl",
|
||||
{ mediaPath, width, height, imageCropMode, animationProcessMode })),
|
||||
'Failed to get crop URL');
|
||||
}
|
||||
|
||||
|
||||
var resource = {
|
||||
getCropUrl: getCropUrl
|
||||
};
|
||||
|
||||
return resource;
|
||||
|
||||
}
|
||||
|
||||
angular.module('umbraco.resources').factory('imageUrlGeneratorResource', imageUrlGeneratorResource);
|
||||
|
||||
})();
|
||||
@@ -41,13 +41,13 @@ ul.sections {
|
||||
|
||||
&:focus .section__name {
|
||||
.tabbing-active & {
|
||||
border: 1px solid;
|
||||
border-color: @gray-9;
|
||||
border: 1px solid @gray-9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.section__name {
|
||||
border: 1px solid transparent;
|
||||
border-radius: 3px;
|
||||
margin-top: 1px;
|
||||
padding: 3px 10px 4px 10px;
|
||||
@@ -75,9 +75,9 @@ ul.sections {
|
||||
opacity: 0.6;
|
||||
transition: opacity .1s linear;
|
||||
}
|
||||
|
||||
|
||||
&:hover i {
|
||||
opacity:1;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
@using Umbraco.Core.Models.PublishedContent
|
||||
@using Umbraco.Web
|
||||
@using Umbraco.Core
|
||||
@using Umbraco.Core.Models
|
||||
@using Umbraco.Web.Composing
|
||||
@inherits Umbraco.Web.Macros.PartialViewMacroPage
|
||||
|
||||
@@ -46,7 +47,7 @@
|
||||
{
|
||||
<div class="col-xs-6 col-md-3">
|
||||
<a href="@item.Url()" class="thumbnail">
|
||||
<img src="@item.GetCropUrl(width:200, height:200)" alt="@item.Name" />
|
||||
<img src="@(item.GetCropUrl(Current.Factory.GetInstance<IImageUrlGenerator>(), width:200, height:200))" alt="@item.Name" />
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -2,20 +2,24 @@
|
||||
@using Umbraco.Web.Templates
|
||||
|
||||
@if (Model.value != null)
|
||||
{
|
||||
{
|
||||
var url = Model.value.image;
|
||||
if(Model.editor.config != null && Model.editor.config.size != null){
|
||||
url += "?width=" + Model.editor.config.size.width;
|
||||
url += "&height=" + Model.editor.config.size.height;
|
||||
|
||||
if(Model.value.focalPoint != null){
|
||||
url += "¢er=" + Model.value.focalPoint.top +"," + Model.value.focalPoint.left;
|
||||
url += "&mode=crop";
|
||||
}
|
||||
url = ImageCropperTemplateCoreExtensions.GetCropUrl(url, Umbraco.Web.Composing.Current.Factory.GetInstance<IImageUrlGenerator>(),
|
||||
width: Model.editor.config.size.width,
|
||||
height: Model.editor.config.size.height,
|
||||
cropDataSet: Model.value.focalPoint == null ? null : new Umbraco.Core.PropertyEditors.ValueConverters.ImageCropperValue
|
||||
{
|
||||
FocalPoint = new Umbraco.Core.PropertyEditors.ValueConverters.ImageCropperValue.ImageCropperFocalPoint
|
||||
{
|
||||
Top = Model.value.focalPoint.top,
|
||||
Left = Model.value.focalPoint.left
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var altText = Model.value.altText ?? Model.value.caption ?? string.Empty;
|
||||
|
||||
|
||||
<img src="@url" alt="@altText">
|
||||
|
||||
if (Model.value.caption != null)
|
||||
|
||||
@@ -321,6 +321,10 @@ namespace Umbraco.Web.Editors
|
||||
"tinyMceApiBaseUrl", _urlHelper.GetUmbracoApiServiceBaseUrl<TinyMceController>(
|
||||
controller => controller.UploadImage())
|
||||
},
|
||||
{
|
||||
"imageUrlGeneratorApiBaseUrl", _urlHelper.GetUmbracoApiServiceBaseUrl<ImageUrlGeneratorController>(
|
||||
controller => controller.GetCropUrl(null, null, null, null, null))
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -22,6 +22,7 @@ using Umbraco.Web.Security;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Core.Mapping;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Web.Editors
|
||||
{
|
||||
@@ -34,6 +35,7 @@ namespace Umbraco.Web.Editors
|
||||
private readonly IMediaFileSystem _mediaFileSystem;
|
||||
private readonly IUmbracoSettingsSection _umbracoSettingsSection;
|
||||
private readonly IIOHelper _ioHelper;
|
||||
private readonly IImageUrlGenerator _imageUrlGenerator;
|
||||
|
||||
public CurrentUserController(
|
||||
IGlobalSettings globalSettings,
|
||||
@@ -48,12 +50,14 @@ namespace Umbraco.Web.Editors
|
||||
IShortStringHelper shortStringHelper,
|
||||
UmbracoMapper umbracoMapper,
|
||||
IUmbracoSettingsSection umbracoSettingsSection,
|
||||
IIOHelper ioHelper)
|
||||
IIOHelper ioHelper,
|
||||
IImageUrlGenerator imageUrlGenerator)
|
||||
: base(globalSettings, umbracoContextAccessor, sqlContext, services, appCaches, logger, runtimeState, umbracoHelper, shortStringHelper, umbracoMapper)
|
||||
{
|
||||
_mediaFileSystem = mediaFileSystem;
|
||||
_umbracoSettingsSection = umbracoSettingsSection ?? throw new ArgumentNullException(nameof(umbracoSettingsSection));
|
||||
_ioHelper = ioHelper ?? throw new ArgumentNullException(nameof(ioHelper));
|
||||
_imageUrlGenerator = imageUrlGenerator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -187,7 +191,7 @@ namespace Umbraco.Web.Editors
|
||||
public async Task<HttpResponseMessage> PostSetAvatar()
|
||||
{
|
||||
//borrow the logic from the user controller
|
||||
return await UsersController.PostSetAvatarInternal(Request, Services.UserService, AppCaches.RuntimeCache, _mediaFileSystem, ShortStringHelper, _umbracoSettingsSection, _ioHelper, Security.GetUserId().ResultOr(0));
|
||||
return await UsersController.PostSetAvatarInternal(Request, Services.UserService, AppCaches.RuntimeCache, _mediaFileSystem, ShortStringHelper, _umbracoSettingsSection, _ioHelper, _imageUrlGenerator, Security.GetUserId().ResultOr(0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
37
src/Umbraco.Web/Editors/ImageUrlGeneratorController.cs
Normal file
37
src/Umbraco.Web/Editors/ImageUrlGeneratorController.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.Mvc;
|
||||
|
||||
namespace Umbraco.Web.Editors
|
||||
{
|
||||
/// <summary>
|
||||
/// The API controller used for getting URLs for images with parameters
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This controller allows for retrieving URLs for processed images, such as resized, cropped,
|
||||
/// or otherwise altered. These can be different based on the IImageUrlGenerator
|
||||
/// implementation in use, and so the BackOffice could should not rely on hard-coded string
|
||||
/// building to generate correct URLs
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public class ImageUrlGeneratorController : UmbracoAuthorizedJsonController
|
||||
{
|
||||
private readonly IImageUrlGenerator _imageUrlGenerator;
|
||||
|
||||
public ImageUrlGeneratorController(IImageUrlGenerator imageUrlGenerator)
|
||||
{
|
||||
_imageUrlGenerator = imageUrlGenerator;
|
||||
}
|
||||
|
||||
public string GetCropUrl(string mediaPath, int? width = null, int? height = null, ImageCropMode? imageCropMode = null, string animationProcessMode = null)
|
||||
{
|
||||
return mediaPath.GetCropUrl(_imageUrlGenerator, null, width: width, height: height, imageCropMode: imageCropMode, animationProcessMode: animationProcessMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ using System.Net;
|
||||
using System.Net.Http;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Web.Media;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi;
|
||||
|
||||
@@ -18,11 +18,13 @@ namespace Umbraco.Web.Editors
|
||||
{
|
||||
private readonly IMediaFileSystem _mediaFileSystem;
|
||||
private readonly IContentSection _contentSection;
|
||||
private readonly IImageUrlGenerator _imageUrlGenerator;
|
||||
|
||||
public ImagesController(IMediaFileSystem mediaFileSystem, IContentSection contentSection)
|
||||
public ImagesController(IMediaFileSystem mediaFileSystem, IContentSection contentSection, IImageUrlGenerator imageUrlGenerator)
|
||||
{
|
||||
_mediaFileSystem = mediaFileSystem;
|
||||
_contentSection = contentSection;
|
||||
_imageUrlGenerator = imageUrlGenerator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -74,12 +76,10 @@ namespace Umbraco.Web.Editors
|
||||
// so ignore and we won't set a last modified date.
|
||||
}
|
||||
|
||||
// TODO: When we abstract imaging for netcore, we are actually just going to be abstracting a URI builder for images, this
|
||||
// is one of those places where this can be used.
|
||||
var rnd = imageLastModified.HasValue ? $"&rnd={imageLastModified:yyyyMMddHHmmss}" : null;
|
||||
var imageUrl = _imageUrlGenerator.GetImageUrl(new ImageUrlGenerationOptions(imagePath) { UpScale = false, Width = width, AnimationProcessMode = "first", ImageCropMode = "max", CacheBusterValue = rnd });
|
||||
|
||||
var rnd = imageLastModified.HasValue ? $"&rnd={imageLastModified:yyyyMMddHHmmss}" : string.Empty;
|
||||
|
||||
response.Headers.Location = new Uri($"{imagePath}?upscale=false&width={width}&animationprocessmode=first&mode=max{rnd}", UriKind.RelativeOrAbsolute);
|
||||
response.Headers.Location = new Uri(imageUrl, UriKind.RelativeOrAbsolute);
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace Umbraco.Web.Editors
|
||||
public class LogController : UmbracoAuthorizedJsonController
|
||||
{
|
||||
private readonly IMediaFileSystem _mediaFileSystem;
|
||||
private readonly IImageUrlGenerator _imageUrlGenerator;
|
||||
|
||||
public LogController(
|
||||
IGlobalSettings globalSettings,
|
||||
@@ -36,10 +37,12 @@ namespace Umbraco.Web.Editors
|
||||
UmbracoHelper umbracoHelper,
|
||||
IMediaFileSystem mediaFileSystem,
|
||||
IShortStringHelper shortStringHelper,
|
||||
UmbracoMapper umbracoMapper)
|
||||
UmbracoMapper umbracoMapper,
|
||||
IImageUrlGenerator imageUrlGenerator)
|
||||
: base(globalSettings, umbracoContextAccessor, sqlContext, services, appCaches, logger, runtimeState, umbracoHelper, shortStringHelper, umbracoMapper)
|
||||
{
|
||||
_mediaFileSystem = mediaFileSystem;
|
||||
_imageUrlGenerator = imageUrlGenerator;
|
||||
}
|
||||
|
||||
[UmbracoApplicationAuthorize(Core.Constants.Applications.Content, Core.Constants.Applications.Media)]
|
||||
@@ -94,7 +97,7 @@ namespace Umbraco.Web.Editors
|
||||
var mappedItems = items.ToList();
|
||||
var userIds = mappedItems.Select(x => x.UserId).ToArray();
|
||||
var userAvatars = Services.UserService.GetUsersById(userIds)
|
||||
.ToDictionary(x => x.Id, x => x.GetUserAvatarUrls(AppCaches.RuntimeCache, _mediaFileSystem));
|
||||
.ToDictionary(x => x.Id, x => x.GetUserAvatarUrls(AppCaches.RuntimeCache, _mediaFileSystem, _imageUrlGenerator));
|
||||
var userNames = Services.UserService.GetUsersById(userIds).ToDictionary(x => x.Id, x => x.Name);
|
||||
foreach (var item in mappedItems)
|
||||
{
|
||||
|
||||
@@ -48,6 +48,7 @@ namespace Umbraco.Web.Editors
|
||||
private readonly IUmbracoSettingsSection _umbracoSettingsSection;
|
||||
private readonly IIOHelper _ioHelper;
|
||||
private readonly ISqlContext _sqlContext;
|
||||
private readonly IImageUrlGenerator _imageUrlGenerator;
|
||||
|
||||
public UsersController(
|
||||
IGlobalSettings globalSettings,
|
||||
@@ -62,13 +63,15 @@ namespace Umbraco.Web.Editors
|
||||
IShortStringHelper shortStringHelper,
|
||||
UmbracoMapper umbracoMapper,
|
||||
IUmbracoSettingsSection umbracoSettingsSection,
|
||||
IIOHelper ioHelper)
|
||||
IIOHelper ioHelper,
|
||||
IImageUrlGenerator imageUrlGenerator)
|
||||
: base(globalSettings, umbracoContextAccessor, sqlContext, services, appCaches, logger, runtimeState, umbracoHelper, shortStringHelper, umbracoMapper)
|
||||
{
|
||||
_mediaFileSystem = mediaFileSystem;
|
||||
_umbracoSettingsSection = umbracoSettingsSection ?? throw new ArgumentNullException(nameof(umbracoSettingsSection));
|
||||
_ioHelper = ioHelper;
|
||||
_sqlContext = sqlContext;
|
||||
_imageUrlGenerator = imageUrlGenerator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -77,7 +80,7 @@ namespace Umbraco.Web.Editors
|
||||
/// <returns></returns>
|
||||
public string[] GetCurrentUserAvatarUrls()
|
||||
{
|
||||
var urls = UmbracoContext.Security.CurrentUser.GetUserAvatarUrls(AppCaches.RuntimeCache, _mediaFileSystem);
|
||||
var urls = UmbracoContext.Security.CurrentUser.GetUserAvatarUrls(AppCaches.RuntimeCache, _mediaFileSystem, _imageUrlGenerator);
|
||||
if (urls == null)
|
||||
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Could not access Gravatar endpoint"));
|
||||
|
||||
@@ -89,10 +92,10 @@ namespace Umbraco.Web.Editors
|
||||
[AdminUsersAuthorize]
|
||||
public async Task<HttpResponseMessage> PostSetAvatar(int id)
|
||||
{
|
||||
return await PostSetAvatarInternal(Request, Services.UserService, AppCaches.RuntimeCache, _mediaFileSystem, ShortStringHelper, _umbracoSettingsSection, _ioHelper, id);
|
||||
return await PostSetAvatarInternal(Request, Services.UserService, AppCaches.RuntimeCache, _mediaFileSystem, ShortStringHelper, _umbracoSettingsSection, _ioHelper, _imageUrlGenerator, id);
|
||||
}
|
||||
|
||||
internal static async Task<HttpResponseMessage> PostSetAvatarInternal(HttpRequestMessage request, IUserService userService, IAppCache cache, IMediaFileSystem mediaFileSystem, IShortStringHelper shortStringHelper, IUmbracoSettingsSection umbracoSettingsSection, IIOHelper ioHelper, int id)
|
||||
internal static async Task<HttpResponseMessage> PostSetAvatarInternal(HttpRequestMessage request, IUserService userService, IAppCache cache, IMediaFileSystem mediaFileSystem, IShortStringHelper shortStringHelper, IUmbracoSettingsSection umbracoSettingsSection, IIOHelper ioHelper, IImageUrlGenerator imageUrlGenerator, int id)
|
||||
{
|
||||
if (request.Content.IsMimeMultipartContent() == false)
|
||||
{
|
||||
@@ -146,7 +149,7 @@ namespace Umbraco.Web.Editors
|
||||
});
|
||||
}
|
||||
|
||||
return request.CreateResponse(HttpStatusCode.OK, user.GetUserAvatarUrls(cache, mediaFileSystem));
|
||||
return request.CreateResponse(HttpStatusCode.OK, user.GetUserAvatarUrls(cache, mediaFileSystem, imageUrlGenerator));
|
||||
}
|
||||
|
||||
[AppendUserModifiedHeader("id")]
|
||||
@@ -180,7 +183,7 @@ namespace Umbraco.Web.Editors
|
||||
_mediaFileSystem.DeleteFile(filePath);
|
||||
}
|
||||
|
||||
return Request.CreateResponse(HttpStatusCode.OK, found.GetUserAvatarUrls(AppCaches.RuntimeCache, _mediaFileSystem));
|
||||
return Request.CreateResponse(HttpStatusCode.OK, found.GetUserAvatarUrls(AppCaches.RuntimeCache, _mediaFileSystem, _imageUrlGenerator));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
379
src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs
Normal file
379
src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs
Normal file
@@ -0,0 +1,379 @@
|
||||
using System;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Globalization;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors.ValueConverters;
|
||||
using Umbraco.Web.Models;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
public static class ImageCropperTemplateCoreExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the ImageProcessor Url by the crop alias (from the "umbracoFile" property alias) on the IPublishedContent item
|
||||
/// </summary>
|
||||
/// <param name="mediaItem">
|
||||
/// The IPublishedContent item.
|
||||
/// </param>
|
||||
/// <param name="cropAlias">
|
||||
/// The crop alias e.g. thumbnail
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The ImageProcessor.Web Url.
|
||||
/// </returns>
|
||||
public static string GetCropUrl(this IPublishedContent mediaItem, string cropAlias, IImageUrlGenerator imageUrlGenerator)
|
||||
{
|
||||
return mediaItem.GetCropUrl(imageUrlGenerator, cropAlias: cropAlias, useCropDimensions: true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ImageProcessor Url by the crop alias using the specified property containing the image cropper Json data on the IPublishedContent item.
|
||||
/// </summary>
|
||||
/// <param name="mediaItem">
|
||||
/// The IPublishedContent item.
|
||||
/// </param>
|
||||
/// <param name="propertyAlias">
|
||||
/// The property alias of the property containing the Json data e.g. umbracoFile
|
||||
/// </param>
|
||||
/// <param name="cropAlias">
|
||||
/// The crop alias e.g. thumbnail
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The ImageProcessor.Web Url.
|
||||
/// </returns>
|
||||
public static string GetCropUrl(this IPublishedContent mediaItem, string propertyAlias, string cropAlias, IImageUrlGenerator imageUrlGenerator)
|
||||
{
|
||||
return mediaItem.GetCropUrl(imageUrlGenerator, propertyAlias: propertyAlias, cropAlias: cropAlias, useCropDimensions: true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ImageProcessor Url from the IPublishedContent item.
|
||||
/// </summary>
|
||||
/// <param name="mediaItem">
|
||||
/// The IPublishedContent item.
|
||||
/// </param>
|
||||
/// <param name="width">
|
||||
/// The width of the output image.
|
||||
/// </param>
|
||||
/// <param name="height">
|
||||
/// The height of the output image.
|
||||
/// </param>
|
||||
/// <param name="propertyAlias">
|
||||
/// Property alias of the property containing the Json data.
|
||||
/// </param>
|
||||
/// <param name="cropAlias">
|
||||
/// The crop alias.
|
||||
/// </param>
|
||||
/// <param name="quality">
|
||||
/// Quality percentage of the output image.
|
||||
/// </param>
|
||||
/// <param name="imageCropMode">
|
||||
/// The image crop mode.
|
||||
/// </param>
|
||||
/// <param name="imageCropAnchor">
|
||||
/// The image crop anchor.
|
||||
/// </param>
|
||||
/// <param name="preferFocalPoint">
|
||||
/// Use focal point, to generate an output image using the focal point instead of the predefined crop
|
||||
/// </param>
|
||||
/// <param name="useCropDimensions">
|
||||
/// Use crop dimensions to have the output image sized according to the predefined crop sizes, this will override the width and height parameters.
|
||||
/// </param>
|
||||
/// <param name="cacheBuster">
|
||||
/// Add a serialized date of the last edit of the item to ensure client cache refresh when updated
|
||||
/// </param>
|
||||
/// <param name="furtherOptions">
|
||||
/// These are any query string parameters (formatted as query strings) that ImageProcessor supports. For example:
|
||||
/// <example>
|
||||
/// <![CDATA[
|
||||
/// furtherOptions: "&bgcolor=fff"
|
||||
/// ]]>
|
||||
/// </example>
|
||||
/// </param>
|
||||
/// <param name="ratioMode">
|
||||
/// Use a dimension as a ratio
|
||||
/// </param>
|
||||
/// <param name="upScale">
|
||||
/// If the image should be upscaled to requested dimensions
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The <see cref="string"/>.
|
||||
/// </returns>
|
||||
public static string GetCropUrl(
|
||||
this IPublishedContent mediaItem,
|
||||
IImageUrlGenerator imageUrlGenerator,
|
||||
int? width = null,
|
||||
int? height = null,
|
||||
string propertyAlias = Constants.Conventions.Media.File,
|
||||
string cropAlias = null,
|
||||
int? quality = null,
|
||||
ImageCropMode? imageCropMode = null,
|
||||
ImageCropAnchor? imageCropAnchor = null,
|
||||
bool preferFocalPoint = false,
|
||||
bool useCropDimensions = false,
|
||||
bool cacheBuster = true,
|
||||
string furtherOptions = null,
|
||||
ImageCropRatioMode? ratioMode = null,
|
||||
bool upScale = true)
|
||||
{
|
||||
if (mediaItem == null) throw new ArgumentNullException("mediaItem");
|
||||
|
||||
var cacheBusterValue = cacheBuster ? mediaItem.UpdateDate.ToFileTimeUtc().ToString(CultureInfo.InvariantCulture) : null;
|
||||
|
||||
if (mediaItem.HasProperty(propertyAlias) == false || mediaItem.HasValue(propertyAlias) == false)
|
||||
return string.Empty;
|
||||
|
||||
var mediaItemUrl = mediaItem.MediaUrl(propertyAlias: propertyAlias);
|
||||
|
||||
//get the default obj from the value converter
|
||||
var cropperValue = mediaItem.Value(propertyAlias);
|
||||
|
||||
//is it strongly typed?
|
||||
var stronglyTyped = cropperValue as ImageCropperValue;
|
||||
if (stronglyTyped != null)
|
||||
{
|
||||
return GetCropUrl(
|
||||
mediaItemUrl, imageUrlGenerator, stronglyTyped, width, height, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions,
|
||||
cacheBusterValue, furtherOptions, ratioMode, upScale);
|
||||
}
|
||||
|
||||
//this shouldn't be the case but we'll check
|
||||
var jobj = cropperValue as JObject;
|
||||
if (jobj != null)
|
||||
{
|
||||
stronglyTyped = jobj.ToObject<ImageCropperValue>();
|
||||
return GetCropUrl(
|
||||
mediaItemUrl, imageUrlGenerator, stronglyTyped, width, height, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions,
|
||||
cacheBusterValue, furtherOptions, ratioMode, upScale);
|
||||
}
|
||||
|
||||
//it's a single string
|
||||
return GetCropUrl(
|
||||
mediaItemUrl, imageUrlGenerator, width, height, mediaItemUrl, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions,
|
||||
cacheBusterValue, furtherOptions, ratioMode, upScale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ImageProcessor Url from the image path.
|
||||
/// </summary>
|
||||
/// <param name="imageUrl">
|
||||
/// The image url.
|
||||
/// </param>
|
||||
/// <param name="width">
|
||||
/// The width of the output image.
|
||||
/// </param>
|
||||
/// <param name="height">
|
||||
/// The height of the output image.
|
||||
/// </param>
|
||||
/// <param name="imageCropperValue">
|
||||
/// The Json data from the Umbraco Core Image Cropper property editor
|
||||
/// </param>
|
||||
/// <param name="cropAlias">
|
||||
/// The crop alias.
|
||||
/// </param>
|
||||
/// <param name="quality">
|
||||
/// Quality percentage of the output image.
|
||||
/// </param>
|
||||
/// <param name="imageCropMode">
|
||||
/// The image crop mode.
|
||||
/// </param>
|
||||
/// <param name="imageCropAnchor">
|
||||
/// The image crop anchor.
|
||||
/// </param>
|
||||
/// <param name="preferFocalPoint">
|
||||
/// Use focal point to generate an output image using the focal point instead of the predefined crop if there is one
|
||||
/// </param>
|
||||
/// <param name="useCropDimensions">
|
||||
/// Use crop dimensions to have the output image sized according to the predefined crop sizes, this will override the width and height parameters
|
||||
/// </param>
|
||||
/// <param name="cacheBusterValue">
|
||||
/// Add a serialized date of the last edit of the item to ensure client cache refresh when updated
|
||||
/// </param>
|
||||
/// <param name="furtherOptions">
|
||||
/// These are any query string parameters (formatted as query strings) that ImageProcessor supports. For example:
|
||||
/// <example>
|
||||
/// <![CDATA[
|
||||
/// furtherOptions: "&bgcolor=fff"
|
||||
/// ]]>
|
||||
/// </example>
|
||||
/// </param>
|
||||
/// <param name="ratioMode">
|
||||
/// Use a dimension as a ratio
|
||||
/// </param>
|
||||
/// <param name="upScale">
|
||||
/// If the image should be upscaled to requested dimensions
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The <see cref="string"/>.
|
||||
/// </returns>
|
||||
public static string GetCropUrl(
|
||||
this string imageUrl,
|
||||
IImageUrlGenerator imageUrlGenerator,
|
||||
int? width = null,
|
||||
int? height = null,
|
||||
string imageCropperValue = null,
|
||||
string cropAlias = null,
|
||||
int? quality = null,
|
||||
ImageCropMode? imageCropMode = null,
|
||||
ImageCropAnchor? imageCropAnchor = null,
|
||||
bool preferFocalPoint = false,
|
||||
bool useCropDimensions = false,
|
||||
string cacheBusterValue = null,
|
||||
string furtherOptions = null,
|
||||
ImageCropRatioMode? ratioMode = null,
|
||||
bool upScale = true)
|
||||
{
|
||||
if (string.IsNullOrEmpty(imageUrl)) return string.Empty;
|
||||
|
||||
ImageCropperValue cropDataSet = null;
|
||||
if (string.IsNullOrEmpty(imageCropperValue) == false && imageCropperValue.DetectIsJson() && (imageCropMode == ImageCropMode.Crop || imageCropMode == null))
|
||||
{
|
||||
cropDataSet = imageCropperValue.DeserializeImageCropperValue();
|
||||
}
|
||||
return GetCropUrl(
|
||||
imageUrl, imageUrlGenerator, cropDataSet, width, height, cropAlias, quality, imageCropMode,
|
||||
imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBusterValue, furtherOptions, ratioMode, upScale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ImageProcessor Url from the image path.
|
||||
/// </summary>
|
||||
/// <param name="imageUrl">
|
||||
/// The image url.
|
||||
/// </param>
|
||||
/// <param name="imageUrlGenerator">
|
||||
/// The generator that will process all the options and the image URL to return a full image urls with all processing options appended
|
||||
/// </param>
|
||||
/// <param name="cropDataSet"></param>
|
||||
/// <param name="width">
|
||||
/// The width of the output image.
|
||||
/// </param>
|
||||
/// <param name="height">
|
||||
/// The height of the output image.
|
||||
/// </param>
|
||||
/// <param name="cropAlias">
|
||||
/// The crop alias.
|
||||
/// </param>
|
||||
/// <param name="quality">
|
||||
/// Quality percentage of the output image.
|
||||
/// </param>
|
||||
/// <param name="imageCropMode">
|
||||
/// The image crop mode.
|
||||
/// </param>
|
||||
/// <param name="imageCropAnchor">
|
||||
/// The image crop anchor.
|
||||
/// </param>
|
||||
/// <param name="preferFocalPoint">
|
||||
/// Use focal point to generate an output image using the focal point instead of the predefined crop if there is one
|
||||
/// </param>
|
||||
/// <param name="useCropDimensions">
|
||||
/// Use crop dimensions to have the output image sized according to the predefined crop sizes, this will override the width and height parameters
|
||||
/// </param>
|
||||
/// <param name="cacheBusterValue">
|
||||
/// Add a serialized date of the last edit of the item to ensure client cache refresh when updated
|
||||
/// </param>
|
||||
/// <param name="furtherOptions">
|
||||
/// These are any query string parameters (formatted as query strings) that ImageProcessor supports. For example:
|
||||
/// <example>
|
||||
/// <![CDATA[
|
||||
/// furtherOptions: "&bgcolor=fff"
|
||||
/// ]]>
|
||||
/// </example>
|
||||
/// </param>
|
||||
/// <param name="ratioMode">
|
||||
/// Use a dimension as a ratio
|
||||
/// </param>
|
||||
/// <param name="upScale">
|
||||
/// If the image should be upscaled to requested dimensions
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The <see cref="string"/>.
|
||||
/// </returns>
|
||||
public static string GetCropUrl(
|
||||
this string imageUrl,
|
||||
IImageUrlGenerator imageUrlGenerator,
|
||||
ImageCropperValue cropDataSet,
|
||||
int? width = null,
|
||||
int? height = null,
|
||||
string cropAlias = null,
|
||||
int? quality = null,
|
||||
ImageCropMode? imageCropMode = null,
|
||||
ImageCropAnchor? imageCropAnchor = null,
|
||||
bool preferFocalPoint = false,
|
||||
bool useCropDimensions = false,
|
||||
string cacheBusterValue = null,
|
||||
string furtherOptions = null,
|
||||
ImageCropRatioMode? ratioMode = null,
|
||||
bool upScale = true,
|
||||
string animationProcessMode = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(imageUrl)) return string.Empty;
|
||||
|
||||
ImageUrlGenerationOptions options;
|
||||
|
||||
if (cropDataSet != null && (imageCropMode == ImageCropMode.Crop || imageCropMode == null))
|
||||
{
|
||||
var crop = cropDataSet.GetCrop(cropAlias);
|
||||
|
||||
// if a crop was specified, but not found, return null
|
||||
if (crop == null && !string.IsNullOrWhiteSpace(cropAlias))
|
||||
return null;
|
||||
|
||||
options = cropDataSet.GetCropBaseOptions(imageUrl, crop, string.IsNullOrWhiteSpace(cropAlias), preferFocalPoint);
|
||||
|
||||
if (crop != null & useCropDimensions)
|
||||
{
|
||||
width = crop.Width;
|
||||
height = crop.Height;
|
||||
}
|
||||
|
||||
// If a predefined crop has been specified & there are no coordinates & no ratio mode, but a width parameter has been passed we can get the crop ratio for the height
|
||||
if (crop != null && string.IsNullOrEmpty(cropAlias) == false && crop.Coordinates == null && ratioMode == null && width != null && height == null)
|
||||
{
|
||||
options.HeightRatio = (decimal)crop.Height / crop.Width;
|
||||
}
|
||||
|
||||
// If a predefined crop has been specified & there are no coordinates & no ratio mode, but a height parameter has been passed we can get the crop ratio for the width
|
||||
if (crop != null && string.IsNullOrEmpty(cropAlias) == false && crop.Coordinates == null && ratioMode == null && width == null && height != null)
|
||||
{
|
||||
options.WidthRatio = (decimal)crop.Width / crop.Height;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
options = new ImageUrlGenerationOptions (imageUrl)
|
||||
{
|
||||
ImageCropMode = (imageCropMode ?? ImageCropMode.Pad).ToString().ToLowerInvariant(),
|
||||
ImageCropAnchor = imageCropAnchor?.ToString().ToLowerInvariant()
|
||||
};
|
||||
}
|
||||
|
||||
options.Quality = quality;
|
||||
options.Width = ratioMode != null && ratioMode.Value == ImageCropRatioMode.Width ? null : width;
|
||||
options.Height = ratioMode != null && ratioMode.Value == ImageCropRatioMode.Height ? null : height;
|
||||
options.AnimationProcessMode = animationProcessMode;
|
||||
|
||||
if (ratioMode == ImageCropRatioMode.Width && height != null)
|
||||
{
|
||||
// if only height specified then assume a square
|
||||
if (width == null) width = height;
|
||||
options.WidthRatio = (decimal)width / (decimal)height;
|
||||
}
|
||||
|
||||
if (ratioMode == ImageCropRatioMode.Height && width != null)
|
||||
{
|
||||
// if only width specified then assume a square
|
||||
if (height == null) height = width;
|
||||
options.HeightRatio = (decimal)height / (decimal)width;
|
||||
}
|
||||
|
||||
options.UpScale = upScale;
|
||||
options.FurtherOptions = furtherOptions;
|
||||
options.CacheBusterValue = cacheBusterValue;
|
||||
|
||||
return imageUrlGenerator.GetImageUrl(options);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,9 @@
|
||||
using System;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors.ValueConverters;
|
||||
using Umbraco.Web.Models;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
@@ -17,419 +12,6 @@ namespace Umbraco.Web
|
||||
/// </summary>
|
||||
public static class ImageCropperTemplateExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the ImageProcessor Url by the crop alias (from the "umbracoFile" property alias) on the IPublishedContent item
|
||||
/// </summary>
|
||||
/// <param name="mediaItem">
|
||||
/// The IPublishedContent item.
|
||||
/// </param>
|
||||
/// <param name="cropAlias">
|
||||
/// The crop alias e.g. thumbnail
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The ImageProcessor.Web Url.
|
||||
/// </returns>
|
||||
public static string GetCropUrl(this IPublishedContent mediaItem, string cropAlias)
|
||||
{
|
||||
return mediaItem.GetCropUrl(cropAlias: cropAlias, useCropDimensions: true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ImageProcessor Url by the crop alias using the specified property containing the image cropper Json data on the IPublishedContent item.
|
||||
/// </summary>
|
||||
/// <param name="mediaItem">
|
||||
/// The IPublishedContent item.
|
||||
/// </param>
|
||||
/// <param name="propertyAlias">
|
||||
/// The property alias of the property containing the Json data e.g. umbracoFile
|
||||
/// </param>
|
||||
/// <param name="cropAlias">
|
||||
/// The crop alias e.g. thumbnail
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The ImageProcessor.Web Url.
|
||||
/// </returns>
|
||||
public static string GetCropUrl(this IPublishedContent mediaItem, string propertyAlias, string cropAlias)
|
||||
{
|
||||
return mediaItem.GetCropUrl(propertyAlias: propertyAlias, cropAlias: cropAlias, useCropDimensions: true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ImageProcessor Url from the IPublishedContent item.
|
||||
/// </summary>
|
||||
/// <param name="mediaItem">
|
||||
/// The IPublishedContent item.
|
||||
/// </param>
|
||||
/// <param name="width">
|
||||
/// The width of the output image.
|
||||
/// </param>
|
||||
/// <param name="height">
|
||||
/// The height of the output image.
|
||||
/// </param>
|
||||
/// <param name="propertyAlias">
|
||||
/// Property alias of the property containing the Json data.
|
||||
/// </param>
|
||||
/// <param name="cropAlias">
|
||||
/// The crop alias.
|
||||
/// </param>
|
||||
/// <param name="quality">
|
||||
/// Quality percentage of the output image.
|
||||
/// </param>
|
||||
/// <param name="imageCropMode">
|
||||
/// The image crop mode.
|
||||
/// </param>
|
||||
/// <param name="imageCropAnchor">
|
||||
/// The image crop anchor.
|
||||
/// </param>
|
||||
/// <param name="preferFocalPoint">
|
||||
/// Use focal point, to generate an output image using the focal point instead of the predefined crop
|
||||
/// </param>
|
||||
/// <param name="useCropDimensions">
|
||||
/// Use crop dimensions to have the output image sized according to the predefined crop sizes, this will override the width and height parameters.
|
||||
/// </param>
|
||||
/// <param name="cacheBuster">
|
||||
/// Add a serialized date of the last edit of the item to ensure client cache refresh when updated
|
||||
/// </param>
|
||||
/// <param name="furtherOptions">
|
||||
/// These are any query string parameters (formatted as query strings) that ImageProcessor supports. For example:
|
||||
/// <example>
|
||||
/// <![CDATA[
|
||||
/// furtherOptions: "&bgcolor=fff"
|
||||
/// ]]>
|
||||
/// </example>
|
||||
/// </param>
|
||||
/// <param name="ratioMode">
|
||||
/// Use a dimension as a ratio
|
||||
/// </param>
|
||||
/// <param name="upScale">
|
||||
/// If the image should be upscaled to requested dimensions
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The <see cref="string"/>.
|
||||
/// </returns>
|
||||
public static string GetCropUrl(
|
||||
this IPublishedContent mediaItem,
|
||||
int? width = null,
|
||||
int? height = null,
|
||||
string propertyAlias = Constants.Conventions.Media.File,
|
||||
string cropAlias = null,
|
||||
int? quality = null,
|
||||
ImageCropMode? imageCropMode = null,
|
||||
ImageCropAnchor? imageCropAnchor = null,
|
||||
bool preferFocalPoint = false,
|
||||
bool useCropDimensions = false,
|
||||
bool cacheBuster = true,
|
||||
string furtherOptions = null,
|
||||
ImageCropRatioMode? ratioMode = null,
|
||||
bool upScale = true)
|
||||
{
|
||||
if (mediaItem == null) throw new ArgumentNullException("mediaItem");
|
||||
|
||||
var cacheBusterValue = cacheBuster ? mediaItem.UpdateDate.ToFileTimeUtc().ToString(CultureInfo.InvariantCulture) : null;
|
||||
|
||||
if (mediaItem.HasProperty(propertyAlias) == false || mediaItem.HasValue(propertyAlias) == false)
|
||||
return string.Empty;
|
||||
|
||||
var mediaItemUrl = mediaItem.MediaUrl(propertyAlias: propertyAlias);
|
||||
|
||||
//get the default obj from the value converter
|
||||
var cropperValue = mediaItem.Value(propertyAlias);
|
||||
|
||||
//is it strongly typed?
|
||||
var stronglyTyped = cropperValue as ImageCropperValue;
|
||||
if (stronglyTyped != null)
|
||||
{
|
||||
return GetCropUrl(
|
||||
mediaItemUrl, stronglyTyped, width, height, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions,
|
||||
cacheBusterValue, furtherOptions, ratioMode, upScale);
|
||||
}
|
||||
|
||||
//this shouldn't be the case but we'll check
|
||||
var jobj = cropperValue as JObject;
|
||||
if (jobj != null)
|
||||
{
|
||||
stronglyTyped = jobj.ToObject<ImageCropperValue>();
|
||||
return GetCropUrl(
|
||||
mediaItemUrl, stronglyTyped, width, height, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions,
|
||||
cacheBusterValue, furtherOptions, ratioMode, upScale);
|
||||
}
|
||||
|
||||
//it's a single string
|
||||
return GetCropUrl(
|
||||
mediaItemUrl, width, height, mediaItemUrl, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions,
|
||||
cacheBusterValue, furtherOptions, ratioMode, upScale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ImageProcessor Url from the image path.
|
||||
/// </summary>
|
||||
/// <param name="imageUrl">
|
||||
/// The image url.
|
||||
/// </param>
|
||||
/// <param name="width">
|
||||
/// The width of the output image.
|
||||
/// </param>
|
||||
/// <param name="height">
|
||||
/// The height of the output image.
|
||||
/// </param>
|
||||
/// <param name="imageCropperValue">
|
||||
/// The Json data from the Umbraco Core Image Cropper property editor
|
||||
/// </param>
|
||||
/// <param name="cropAlias">
|
||||
/// The crop alias.
|
||||
/// </param>
|
||||
/// <param name="quality">
|
||||
/// Quality percentage of the output image.
|
||||
/// </param>
|
||||
/// <param name="imageCropMode">
|
||||
/// The image crop mode.
|
||||
/// </param>
|
||||
/// <param name="imageCropAnchor">
|
||||
/// The image crop anchor.
|
||||
/// </param>
|
||||
/// <param name="preferFocalPoint">
|
||||
/// Use focal point to generate an output image using the focal point instead of the predefined crop if there is one
|
||||
/// </param>
|
||||
/// <param name="useCropDimensions">
|
||||
/// Use crop dimensions to have the output image sized according to the predefined crop sizes, this will override the width and height parameters
|
||||
/// </param>
|
||||
/// <param name="cacheBusterValue">
|
||||
/// Add a serialized date of the last edit of the item to ensure client cache refresh when updated
|
||||
/// </param>
|
||||
/// <param name="furtherOptions">
|
||||
/// These are any query string parameters (formatted as query strings) that ImageProcessor supports. For example:
|
||||
/// <example>
|
||||
/// <![CDATA[
|
||||
/// furtherOptions: "&bgcolor=fff"
|
||||
/// ]]>
|
||||
/// </example>
|
||||
/// </param>
|
||||
/// <param name="ratioMode">
|
||||
/// Use a dimension as a ratio
|
||||
/// </param>
|
||||
/// <param name="upScale">
|
||||
/// If the image should be upscaled to requested dimensions
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The <see cref="string"/>.
|
||||
/// </returns>
|
||||
public static string GetCropUrl(
|
||||
this string imageUrl,
|
||||
int? width = null,
|
||||
int? height = null,
|
||||
string imageCropperValue = null,
|
||||
string cropAlias = null,
|
||||
int? quality = null,
|
||||
ImageCropMode? imageCropMode = null,
|
||||
ImageCropAnchor? imageCropAnchor = null,
|
||||
bool preferFocalPoint = false,
|
||||
bool useCropDimensions = false,
|
||||
string cacheBusterValue = null,
|
||||
string furtherOptions = null,
|
||||
ImageCropRatioMode? ratioMode = null,
|
||||
bool upScale = true)
|
||||
{
|
||||
if (string.IsNullOrEmpty(imageUrl)) return string.Empty;
|
||||
|
||||
ImageCropperValue cropDataSet = null;
|
||||
if (string.IsNullOrEmpty(imageCropperValue) == false && imageCropperValue.DetectIsJson() && (imageCropMode == ImageCropMode.Crop || imageCropMode == null))
|
||||
{
|
||||
cropDataSet = imageCropperValue.DeserializeImageCropperValue();
|
||||
}
|
||||
return GetCropUrl(
|
||||
imageUrl, cropDataSet, width, height, cropAlias, quality, imageCropMode,
|
||||
imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBusterValue, furtherOptions, ratioMode, upScale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ImageProcessor Url from the image path.
|
||||
/// </summary>
|
||||
/// <param name="imageUrl">
|
||||
/// The image url.
|
||||
/// </param>
|
||||
/// <param name="cropDataSet"></param>
|
||||
/// <param name="width">
|
||||
/// The width of the output image.
|
||||
/// </param>
|
||||
/// <param name="height">
|
||||
/// The height of the output image.
|
||||
/// </param>
|
||||
/// <param name="cropAlias">
|
||||
/// The crop alias.
|
||||
/// </param>
|
||||
/// <param name="quality">
|
||||
/// Quality percentage of the output image.
|
||||
/// </param>
|
||||
/// <param name="imageCropMode">
|
||||
/// The image crop mode.
|
||||
/// </param>
|
||||
/// <param name="imageCropAnchor">
|
||||
/// The image crop anchor.
|
||||
/// </param>
|
||||
/// <param name="preferFocalPoint">
|
||||
/// Use focal point to generate an output image using the focal point instead of the predefined crop if there is one
|
||||
/// </param>
|
||||
/// <param name="useCropDimensions">
|
||||
/// Use crop dimensions to have the output image sized according to the predefined crop sizes, this will override the width and height parameters
|
||||
/// </param>
|
||||
/// <param name="cacheBusterValue">
|
||||
/// Add a serialized date of the last edit of the item to ensure client cache refresh when updated
|
||||
/// </param>
|
||||
/// <param name="furtherOptions">
|
||||
/// These are any query string parameters (formatted as query strings) that ImageProcessor supports. For example:
|
||||
/// <example>
|
||||
/// <![CDATA[
|
||||
/// furtherOptions: "&bgcolor=fff"
|
||||
/// ]]>
|
||||
/// </example>
|
||||
/// </param>
|
||||
/// <param name="ratioMode">
|
||||
/// Use a dimension as a ratio
|
||||
/// </param>
|
||||
/// <param name="upScale">
|
||||
/// If the image should be upscaled to requested dimensions
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The <see cref="string"/>.
|
||||
/// </returns>
|
||||
public static string GetCropUrl(
|
||||
this string imageUrl,
|
||||
ImageCropperValue cropDataSet,
|
||||
int? width = null,
|
||||
int? height = null,
|
||||
string cropAlias = null,
|
||||
int? quality = null,
|
||||
ImageCropMode? imageCropMode = null,
|
||||
ImageCropAnchor? imageCropAnchor = null,
|
||||
bool preferFocalPoint = false,
|
||||
bool useCropDimensions = false,
|
||||
string cacheBusterValue = null,
|
||||
string furtherOptions = null,
|
||||
ImageCropRatioMode? ratioMode = null,
|
||||
bool upScale = true)
|
||||
{
|
||||
if (string.IsNullOrEmpty(imageUrl) == false)
|
||||
{
|
||||
var imageProcessorUrl = new StringBuilder();
|
||||
|
||||
if (cropDataSet != null && (imageCropMode == ImageCropMode.Crop || imageCropMode == null))
|
||||
{
|
||||
var crop = cropDataSet.GetCrop(cropAlias);
|
||||
|
||||
// if a crop was specified, but not found, return null
|
||||
if (crop == null && !string.IsNullOrWhiteSpace(cropAlias))
|
||||
return null;
|
||||
|
||||
imageProcessorUrl.Append(imageUrl);
|
||||
cropDataSet.AppendCropBaseUrl(imageProcessorUrl, crop, string.IsNullOrWhiteSpace(cropAlias), preferFocalPoint);
|
||||
|
||||
if (crop != null & useCropDimensions)
|
||||
{
|
||||
width = crop.Width;
|
||||
height = crop.Height;
|
||||
}
|
||||
|
||||
// If a predefined crop has been specified & there are no coordinates & no ratio mode, but a width parameter has been passed we can get the crop ratio for the height
|
||||
if (crop != null && string.IsNullOrEmpty(cropAlias) == false && crop.Coordinates == null && ratioMode == null && width != null && height == null)
|
||||
{
|
||||
var heightRatio = (decimal)crop.Height / (decimal)crop.Width;
|
||||
imageProcessorUrl.Append("&heightratio=" + heightRatio.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
// If a predefined crop has been specified & there are no coordinates & no ratio mode, but a height parameter has been passed we can get the crop ratio for the width
|
||||
if (crop != null && string.IsNullOrEmpty(cropAlias) == false && crop.Coordinates == null && ratioMode == null && width == null && height != null)
|
||||
{
|
||||
var widthRatio = (decimal)crop.Width / (decimal)crop.Height;
|
||||
imageProcessorUrl.Append("&widthratio=" + widthRatio.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
imageProcessorUrl.Append(imageUrl);
|
||||
|
||||
if (imageCropMode == null)
|
||||
{
|
||||
imageCropMode = ImageCropMode.Pad;
|
||||
}
|
||||
|
||||
imageProcessorUrl.Append("?mode=" + imageCropMode.ToString().ToLower());
|
||||
|
||||
if (imageCropAnchor != null)
|
||||
{
|
||||
imageProcessorUrl.Append("&anchor=" + imageCropAnchor.ToString().ToLower());
|
||||
}
|
||||
}
|
||||
|
||||
var hasFormat = furtherOptions != null && furtherOptions.InvariantContains("&format=");
|
||||
|
||||
//Only put quality here, if we don't have a format specified.
|
||||
//Otherwise we need to put quality at the end to avoid it being overridden by the format.
|
||||
if (quality != null && hasFormat == false)
|
||||
{
|
||||
imageProcessorUrl.Append("&quality=" + quality);
|
||||
}
|
||||
|
||||
if (width != null && ratioMode != ImageCropRatioMode.Width)
|
||||
{
|
||||
imageProcessorUrl.Append("&width=" + width);
|
||||
}
|
||||
|
||||
if (height != null && ratioMode != ImageCropRatioMode.Height)
|
||||
{
|
||||
imageProcessorUrl.Append("&height=" + height);
|
||||
}
|
||||
|
||||
if (ratioMode == ImageCropRatioMode.Width && height != null)
|
||||
{
|
||||
// if only height specified then assume a square
|
||||
if (width == null)
|
||||
{
|
||||
width = height;
|
||||
}
|
||||
|
||||
var widthRatio = (decimal)width / (decimal)height;
|
||||
imageProcessorUrl.Append("&widthratio=" + widthRatio.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
if (ratioMode == ImageCropRatioMode.Height && width != null)
|
||||
{
|
||||
// if only width specified then assume a square
|
||||
if (height == null)
|
||||
{
|
||||
height = width;
|
||||
}
|
||||
|
||||
var heightRatio = (decimal)height / (decimal)width;
|
||||
imageProcessorUrl.Append("&heightratio=" + heightRatio.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
if (upScale == false)
|
||||
{
|
||||
imageProcessorUrl.Append("&upscale=false");
|
||||
}
|
||||
|
||||
if (furtherOptions != null)
|
||||
{
|
||||
imageProcessorUrl.Append(furtherOptions);
|
||||
}
|
||||
|
||||
//If furtherOptions contains a format, we need to put the quality after the format.
|
||||
if (quality != null && hasFormat)
|
||||
{
|
||||
imageProcessorUrl.Append("&quality=" + quality);
|
||||
}
|
||||
|
||||
if (cacheBusterValue != null)
|
||||
{
|
||||
imageProcessorUrl.Append("&rnd=").Append(cacheBusterValue);
|
||||
}
|
||||
|
||||
return imageProcessorUrl.ToString();
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
internal static ImageCropperValue DeserializeImageCropperValue(this string json)
|
||||
{
|
||||
var imageCrops = new ImageCropperValue();
|
||||
|
||||
64
src/Umbraco.Web/Models/ImageProcessorImageUrlGenerator.cs
Normal file
64
src/Umbraco.Web/Models/ImageProcessorImageUrlGenerator.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
{
|
||||
internal class ImageProcessorImageUrlGenerator : IImageUrlGenerator
|
||||
{
|
||||
public string GetImageUrl(ImageUrlGenerationOptions options)
|
||||
{
|
||||
if (options == null) return null;
|
||||
|
||||
var imageProcessorUrl = new StringBuilder(options.ImageUrl ?? string.Empty);
|
||||
|
||||
if (options.FocalPoint != null) AppendFocalPoint(imageProcessorUrl, options);
|
||||
else if (options.Crop != null) AppendCrop(imageProcessorUrl, options);
|
||||
else if (options.DefaultCrop) imageProcessorUrl.Append("?anchor=center&mode=crop");
|
||||
else
|
||||
{
|
||||
imageProcessorUrl.Append("?mode=").Append((options.ImageCropMode ?? "crop").ToLower());
|
||||
|
||||
if (options.ImageCropAnchor != null) imageProcessorUrl.Append("&anchor=").Append(options.ImageCropAnchor.ToLower());
|
||||
}
|
||||
|
||||
var hasFormat = options.FurtherOptions != null && options.FurtherOptions.InvariantContains("&format=");
|
||||
|
||||
//Only put quality here, if we don't have a format specified.
|
||||
//Otherwise we need to put quality at the end to avoid it being overridden by the format.
|
||||
if (options.Quality != null && hasFormat == false) imageProcessorUrl.Append("&quality=").Append(options.Quality);
|
||||
if (options.HeightRatio != null) imageProcessorUrl.Append("&heightratio=").Append(options.HeightRatio.Value.ToString(CultureInfo.InvariantCulture));
|
||||
if (options.WidthRatio != null) imageProcessorUrl.Append("&widthratio=").Append(options.WidthRatio.Value.ToString(CultureInfo.InvariantCulture));
|
||||
if (options.Width != null) imageProcessorUrl.Append("&width=").Append(options.Width);
|
||||
if (options.Height != null) imageProcessorUrl.Append("&height=").Append(options.Height);
|
||||
if (options.UpScale == false) imageProcessorUrl.Append("&upscale=false");
|
||||
if (options.AnimationProcessMode != null) imageProcessorUrl.Append("&animationprocessmode=").Append(options.AnimationProcessMode);
|
||||
if (options.FurtherOptions != null) imageProcessorUrl.Append(options.FurtherOptions);
|
||||
|
||||
//If furtherOptions contains a format, we need to put the quality after the format.
|
||||
if (options.Quality != null && hasFormat) imageProcessorUrl.Append("&quality=").Append(options.Quality);
|
||||
if (options.CacheBusterValue != null) imageProcessorUrl.Append("&rnd=").Append(options.CacheBusterValue);
|
||||
|
||||
return imageProcessorUrl.ToString();
|
||||
}
|
||||
|
||||
private void AppendFocalPoint(StringBuilder imageProcessorUrl, ImageUrlGenerationOptions options)
|
||||
{
|
||||
imageProcessorUrl.Append("?center=");
|
||||
imageProcessorUrl.Append(options.FocalPoint.Top.ToString(CultureInfo.InvariantCulture)).Append(",");
|
||||
imageProcessorUrl.Append(options.FocalPoint.Left.ToString(CultureInfo.InvariantCulture));
|
||||
imageProcessorUrl.Append("&mode=crop");
|
||||
}
|
||||
|
||||
private void AppendCrop(StringBuilder imageProcessorUrl, ImageUrlGenerationOptions options)
|
||||
{
|
||||
imageProcessorUrl.Append("?crop=");
|
||||
imageProcessorUrl.Append(options.Crop.X1.ToString(CultureInfo.InvariantCulture)).Append(",");
|
||||
imageProcessorUrl.Append(options.Crop.Y1.ToString(CultureInfo.InvariantCulture)).Append(",");
|
||||
imageProcessorUrl.Append(options.Crop.X2.ToString(CultureInfo.InvariantCulture)).Append(",");
|
||||
imageProcessorUrl.Append(options.Crop.Y2.ToString(CultureInfo.InvariantCulture));
|
||||
imageProcessorUrl.Append("&cropmode=percentage");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,9 +31,11 @@ namespace Umbraco.Web.Models.Mapping
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
private readonly IMediaFileSystem _mediaFileSystem;
|
||||
private readonly IShortStringHelper _shortStringHelper;
|
||||
private readonly IImageUrlGenerator _imageUrlGenerator;
|
||||
|
||||
public UserMapDefinition(ILocalizedTextService textService, IUserService userService, IEntityService entityService, ISectionService sectionService,
|
||||
AppCaches appCaches, ActionCollection actions, IGlobalSettings globalSettings, IMediaFileSystem mediaFileSystem, IShortStringHelper shortStringHelper)
|
||||
AppCaches appCaches, ActionCollection actions, IGlobalSettings globalSettings, IMediaFileSystem mediaFileSystem, IShortStringHelper shortStringHelper,
|
||||
IImageUrlGenerator imageUrlGenerator)
|
||||
{
|
||||
_sectionService = sectionService;
|
||||
_entityService = entityService;
|
||||
@@ -44,6 +46,7 @@ namespace Umbraco.Web.Models.Mapping
|
||||
_globalSettings = globalSettings;
|
||||
_mediaFileSystem = mediaFileSystem;
|
||||
_shortStringHelper = shortStringHelper;
|
||||
_imageUrlGenerator = imageUrlGenerator;
|
||||
}
|
||||
|
||||
public void DefineMaps(UmbracoMapper mapper)
|
||||
@@ -279,7 +282,7 @@ namespace Umbraco.Web.Models.Mapping
|
||||
private void Map(IUser source, UserDisplay target, MapperContext context)
|
||||
{
|
||||
target.AvailableCultures = _textService.GetSupportedCultures().ToDictionary(x => x.Name, x => x.DisplayName);
|
||||
target.Avatars = source.GetUserAvatarUrls(_appCaches.RuntimeCache, _mediaFileSystem);
|
||||
target.Avatars = source.GetUserAvatarUrls(_appCaches.RuntimeCache, _mediaFileSystem, _imageUrlGenerator);
|
||||
target.CalculatedStartContentIds = GetStartNodes(source.CalculateContentStartNodeIds(_entityService), UmbracoObjectTypes.Document, "content/contentRoot", context);
|
||||
target.CalculatedStartMediaIds = GetStartNodes(source.CalculateMediaStartNodeIds(_entityService), UmbracoObjectTypes.Media, "media/mediaRoot", context);
|
||||
target.CreateDate = source.CreateDate;
|
||||
@@ -310,7 +313,7 @@ namespace Umbraco.Web.Models.Mapping
|
||||
//Loading in the user avatar's requires an external request if they don't have a local file avatar, this means that initial load of paging may incur a cost
|
||||
//Alternatively, if this is annoying the back office UI would need to be updated to request the avatars for the list of users separately so it doesn't look
|
||||
//like the load time is waiting.
|
||||
target.Avatars = source.GetUserAvatarUrls(_appCaches.RuntimeCache, _mediaFileSystem);
|
||||
target.Avatars = source.GetUserAvatarUrls(_appCaches.RuntimeCache, _mediaFileSystem, _imageUrlGenerator);
|
||||
target.Culture = source.GetUserCulture(_textService, _globalSettings).ToString();
|
||||
target.Email = source.Email;
|
||||
target.EmailHash = source.Email.ToLowerInvariant().Trim().GenerateHash();
|
||||
@@ -329,7 +332,7 @@ namespace Umbraco.Web.Models.Mapping
|
||||
private void Map(IUser source, UserDetail target, MapperContext context)
|
||||
{
|
||||
target.AllowedSections = source.AllowedSections;
|
||||
target.Avatars = source.GetUserAvatarUrls(_appCaches.RuntimeCache, _mediaFileSystem);
|
||||
target.Avatars = source.GetUserAvatarUrls(_appCaches.RuntimeCache, _mediaFileSystem, _imageUrlGenerator);
|
||||
target.Culture = source.GetUserCulture(_textService, _globalSettings).ToString();
|
||||
target.Email = source.Email;
|
||||
target.EmailHash = source.Email.ToLowerInvariant().Trim().GenerateHash();
|
||||
|
||||
@@ -3,6 +3,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
@@ -38,6 +39,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
private readonly HtmlImageSourceParser _imageSourceParser;
|
||||
private readonly RichTextEditorPastedImages _pastedImages;
|
||||
private readonly HtmlLocalLinkParser _localLinkParser;
|
||||
private readonly IImageUrlGenerator _imageUrlGenerator;
|
||||
|
||||
public GridPropertyEditor(
|
||||
ILogger logger,
|
||||
@@ -51,7 +53,8 @@ namespace Umbraco.Web.PropertyEditors
|
||||
RichTextEditorPastedImages pastedImages,
|
||||
HtmlLocalLinkParser localLinkParser,
|
||||
IIOHelper ioHelper,
|
||||
IShortStringHelper shortStringHelper)
|
||||
IShortStringHelper shortStringHelper,
|
||||
IImageUrlGenerator imageUrlGenerator)
|
||||
: base(logger, dataTypeService, localizationService, localizedTextService, shortStringHelper)
|
||||
{
|
||||
_umbracoContextAccessor = umbracoContextAccessor;
|
||||
@@ -64,6 +67,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
_imageSourceParser = imageSourceParser;
|
||||
_pastedImages = pastedImages;
|
||||
_localLinkParser = localLinkParser;
|
||||
_imageUrlGenerator = imageUrlGenerator;
|
||||
}
|
||||
|
||||
public override IPropertyIndexValueFactory PropertyIndexValueFactory => new GridPropertyIndexValueFactory();
|
||||
@@ -72,7 +76,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// Overridden to ensure that the value is validated
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override IDataValueEditor CreateValueEditor() => new GridPropertyValueEditor(Attribute, _mediaService, _contentTypeBaseServiceProvider, _umbracoContextAccessor, _logger, DataTypeService, LocalizationService, LocalizedTextService, _imageSourceParser, _pastedImages, _localLinkParser, ShortStringHelper);
|
||||
protected override IDataValueEditor CreateValueEditor() => new GridPropertyValueEditor(Attribute, _mediaService, _contentTypeBaseServiceProvider, _umbracoContextAccessor, _logger, DataTypeService, LocalizationService, LocalizedTextService, _imageSourceParser, _pastedImages, _localLinkParser, ShortStringHelper, _imageUrlGenerator);
|
||||
|
||||
protected override IConfigurationEditor CreateConfigurationEditor() => new GridConfigurationEditor(_ioHelper);
|
||||
|
||||
@@ -83,6 +87,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
private readonly RichTextEditorPastedImages _pastedImages;
|
||||
private readonly RichTextPropertyEditor.RichTextPropertyValueEditor _richTextPropertyValueEditor;
|
||||
private readonly MediaPickerPropertyEditor.MediaPickerPropertyValueEditor _mediaPickerPropertyValueEditor;
|
||||
private readonly IImageUrlGenerator _imageUrlGenerator;
|
||||
|
||||
public GridPropertyValueEditor(
|
||||
DataEditorAttribute attribute,
|
||||
@@ -96,14 +101,16 @@ namespace Umbraco.Web.PropertyEditors
|
||||
HtmlImageSourceParser imageSourceParser,
|
||||
RichTextEditorPastedImages pastedImages,
|
||||
HtmlLocalLinkParser localLinkParser,
|
||||
IShortStringHelper shortStringHelper)
|
||||
IShortStringHelper shortStringHelper,
|
||||
IImageUrlGenerator imageUrlGenerator)
|
||||
: base(dataTypeService, localizationService, localizedTextService, shortStringHelper, attribute)
|
||||
{
|
||||
_umbracoContextAccessor = umbracoContextAccessor;
|
||||
_imageSourceParser = imageSourceParser;
|
||||
_pastedImages = pastedImages;
|
||||
_richTextPropertyValueEditor = new RichTextPropertyEditor.RichTextPropertyValueEditor(attribute, umbracoContextAccessor, dataTypeService, localizationService, localizedTextService, shortStringHelper, imageSourceParser, localLinkParser, pastedImages);
|
||||
_richTextPropertyValueEditor = new RichTextPropertyEditor.RichTextPropertyValueEditor(attribute, umbracoContextAccessor, dataTypeService, localizationService, localizedTextService, shortStringHelper, imageSourceParser, localLinkParser, pastedImages, imageUrlGenerator);
|
||||
_mediaPickerPropertyValueEditor = new MediaPickerPropertyEditor.MediaPickerPropertyValueEditor(dataTypeService, localizationService, localizedTextService, shortStringHelper, attribute);
|
||||
_imageUrlGenerator = imageUrlGenerator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -138,7 +145,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
// Parse the HTML
|
||||
var html = rte.Value?.ToString();
|
||||
|
||||
var parseAndSavedTempImages = _pastedImages.FindAndPersistPastedTempImages(html, mediaParentId, userId);
|
||||
var parseAndSavedTempImages = _pastedImages.FindAndPersistPastedTempImages(html, mediaParentId, userId, _imageUrlGenerator);
|
||||
var editorValueWithMediaUrlsRemoved = _imageSourceParser.RemoveImageSources(parseAndSavedTempImages);
|
||||
|
||||
rte.Value = editorValueWithMediaUrlsRemoved;
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <param name="mediaParentFolder"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <returns></returns>
|
||||
internal string FindAndPersistPastedTempImages(string html, Guid mediaParentFolder, int userId)
|
||||
internal string FindAndPersistPastedTempImages(string html, Guid mediaParentFolder, int userId, IImageUrlGenerator imageUrlGenerator)
|
||||
{
|
||||
// Find all img's that has data-tmpimg attribute
|
||||
// Use HTML Agility Pack - https://html-agility-pack.net
|
||||
@@ -116,7 +116,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
|
||||
if (width != int.MinValue && height != int.MinValue)
|
||||
{
|
||||
location = $"{location}?width={width}&height={height}&mode=max";
|
||||
location = imageUrlGenerator.GetImageUrl(new ImageUrlGenerationOptions(location) { ImageCropMode = "max", Width = width, Height = height });
|
||||
}
|
||||
|
||||
img.SetAttributeValue("src", location);
|
||||
|
||||
@@ -33,6 +33,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
private readonly HtmlLocalLinkParser _localLinkParser;
|
||||
private readonly RichTextEditorPastedImages _pastedImages;
|
||||
private readonly IIOHelper _ioHelper;
|
||||
private readonly IImageUrlGenerator _imageUrlGenerator;
|
||||
|
||||
/// <summary>
|
||||
/// The constructor will setup the property editor based on the attribute if one is found
|
||||
@@ -49,7 +50,8 @@ namespace Umbraco.Web.PropertyEditors
|
||||
RichTextEditorPastedImages pastedImages,
|
||||
IShortStringHelper shortStringHelper,
|
||||
IIOHelper ioHelper,
|
||||
ILocalizedTextService localizedTextService)
|
||||
ILocalizedTextService localizedTextService,
|
||||
IImageUrlGenerator imageUrlGenerator)
|
||||
: base(logger, dataTypeService, localizationService, localizedTextService, shortStringHelper)
|
||||
{
|
||||
_umbracoContextAccessor = umbracoContextAccessor;
|
||||
@@ -57,13 +59,14 @@ namespace Umbraco.Web.PropertyEditors
|
||||
_localLinkParser = localLinkParser;
|
||||
_pastedImages = pastedImages;
|
||||
_ioHelper = ioHelper;
|
||||
_imageUrlGenerator = imageUrlGenerator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a custom value editor
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override IDataValueEditor CreateValueEditor() => new RichTextPropertyValueEditor(Attribute, _umbracoContextAccessor, DataTypeService, LocalizationService, LocalizedTextService, ShortStringHelper, _imageSourceParser, _localLinkParser, _pastedImages);
|
||||
protected override IDataValueEditor CreateValueEditor() => new RichTextPropertyValueEditor(Attribute, _umbracoContextAccessor, DataTypeService, LocalizationService, LocalizedTextService, ShortStringHelper, _imageSourceParser, _localLinkParser, _pastedImages, _imageUrlGenerator);
|
||||
|
||||
protected override IConfigurationEditor CreateConfigurationEditor() => new RichTextConfigurationEditor(_ioHelper);
|
||||
|
||||
@@ -78,6 +81,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
private readonly HtmlImageSourceParser _imageSourceParser;
|
||||
private readonly HtmlLocalLinkParser _localLinkParser;
|
||||
private readonly RichTextEditorPastedImages _pastedImages;
|
||||
private readonly IImageUrlGenerator _imageUrlGenerator;
|
||||
|
||||
public RichTextPropertyValueEditor(
|
||||
DataEditorAttribute attribute,
|
||||
@@ -88,13 +92,15 @@ namespace Umbraco.Web.PropertyEditors
|
||||
IShortStringHelper shortStringHelper,
|
||||
HtmlImageSourceParser imageSourceParser,
|
||||
HtmlLocalLinkParser localLinkParser,
|
||||
RichTextEditorPastedImages pastedImages)
|
||||
RichTextEditorPastedImages pastedImages,
|
||||
IImageUrlGenerator imageUrlGenerator)
|
||||
: base(dataTypeService, localizationService,localizedTextService, shortStringHelper, attribute)
|
||||
{
|
||||
_umbracoContextAccessor = umbracoContextAccessor;
|
||||
_imageSourceParser = imageSourceParser;
|
||||
_localLinkParser = localLinkParser;
|
||||
_pastedImages = pastedImages;
|
||||
_imageUrlGenerator = imageUrlGenerator;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -148,7 +154,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
var mediaParent = config?.MediaParentId;
|
||||
var mediaParentId = mediaParent == null ? Guid.Empty : mediaParent.Guid;
|
||||
|
||||
var parseAndSavedTempImages = _pastedImages.FindAndPersistPastedTempImages(editorValue.Value.ToString(), mediaParentId, userId);
|
||||
var parseAndSavedTempImages = _pastedImages.FindAndPersistPastedTempImages(editorValue.Value.ToString(), mediaParentId, userId, _imageUrlGenerator);
|
||||
var editorValueWithMediaUrlsRemoved = _imageSourceParser.RemoveImageSources(parseAndSavedTempImages);
|
||||
var parsed = MacroTagParser.FormatRichTextContentForPersistence(editorValueWithMediaUrlsRemoved);
|
||||
|
||||
|
||||
@@ -47,6 +47,8 @@ using Umbraco.Web.WebApi;
|
||||
using Current = Umbraco.Web.Composing.Current;
|
||||
using Umbraco.Web.PropertyEditors;
|
||||
using Umbraco.Examine;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Web.Models;
|
||||
|
||||
namespace Umbraco.Web.Runtime
|
||||
{
|
||||
@@ -204,6 +206,8 @@ namespace Umbraco.Web.Runtime
|
||||
composition.MediaUrlProviders()
|
||||
.Append<DefaultMediaUrlProvider>();
|
||||
|
||||
composition.RegisterUnique<IImageUrlGenerator, ImageProcessorImageUrlGenerator>();
|
||||
|
||||
composition.RegisterUnique<IContentLastChanceFinder, ContentFinderByConfigured404>();
|
||||
|
||||
composition.ContentFinders()
|
||||
|
||||
@@ -148,6 +148,7 @@
|
||||
<Compile Include="Editors\BackOfficePreviewModel.cs" />
|
||||
<Compile Include="Editors\Filters\ContentSaveModelValidator.cs" />
|
||||
<Compile Include="Editors\Filters\MediaSaveModelValidator.cs" />
|
||||
<Compile Include="Editors\ImageUrlGeneratorController.cs" />
|
||||
<Compile Include="Editors\PackageController.cs" />
|
||||
<Compile Include="Editors\KeepAliveController.cs" />
|
||||
<Compile Include="Editors\MacrosController.cs" />
|
||||
@@ -156,6 +157,7 @@
|
||||
<Compile Include="FrameworkMarchal.cs" />
|
||||
<Compile Include="Hosting\AspNetHostingEnvironment.cs" />
|
||||
<Compile Include="HttpContextExtensions.cs" />
|
||||
<Compile Include="ImageCropperTemplateCoreExtensions.cs" />
|
||||
<Compile Include="IUmbracoContextFactory.cs" />
|
||||
<Compile Include="Install\ChangesMonitor.cs" />
|
||||
<Compile Include="Logging\OwinLogger.cs" />
|
||||
@@ -172,6 +174,7 @@
|
||||
<Compile Include="Models\Identity\IdentityMapDefinition.cs" />
|
||||
<Compile Include="Models\Identity\IdentityUser.cs" />
|
||||
<Compile Include="Models\Identity\UserLoginInfoWrapper.cs" />
|
||||
<Compile Include="Models\ImageProcessorImageUrlGenerator.cs" />
|
||||
<Compile Include="Models\Mapping\CommonMapper.cs" />
|
||||
<Compile Include="Models\Mapping\ContentMapDefinition.cs" />
|
||||
<Compile Include="Models\Mapping\ContentPropertyBasicMapper.cs" />
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors.ValueConverters;
|
||||
using Umbraco.Web.Composing;
|
||||
@@ -37,11 +38,11 @@ namespace Umbraco.Web
|
||||
/// set to false if using the result of this method for CSS.
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
public static IHtmlString GetCropUrl(this UrlHelper urlHelper, IPublishedContent mediaItem, string cropAlias, bool htmlEncode = true)
|
||||
public static IHtmlString GetCropUrl(this UrlHelper urlHelper, IPublishedContent mediaItem, IImageUrlGenerator imageUrlGenerator, string cropAlias, bool htmlEncode = true)
|
||||
{
|
||||
if (mediaItem == null) return EmptyHtmlString;
|
||||
|
||||
var url = mediaItem.GetCropUrl(cropAlias: cropAlias, useCropDimensions: true);
|
||||
var url = mediaItem.GetCropUrl(imageUrlGenerator, cropAlias: cropAlias, useCropDimensions: true);
|
||||
return htmlEncode ? new HtmlString(HttpUtility.HtmlEncode(url)) : new HtmlString(url);
|
||||
}
|
||||
|
||||
@@ -65,11 +66,11 @@ namespace Umbraco.Web
|
||||
/// <returns>
|
||||
/// The ImageProcessor.Web Url.
|
||||
/// </returns>
|
||||
public static IHtmlString GetCropUrl(this UrlHelper urlHelper, IPublishedContent mediaItem, string propertyAlias, string cropAlias, bool htmlEncode = true)
|
||||
public static IHtmlString GetCropUrl(this UrlHelper urlHelper, IPublishedContent mediaItem, string propertyAlias, string cropAlias, IImageUrlGenerator imageUrlGenerator, bool htmlEncode = true)
|
||||
{
|
||||
if (mediaItem == null) return EmptyHtmlString;
|
||||
|
||||
var url = mediaItem.GetCropUrl(propertyAlias: propertyAlias, cropAlias: cropAlias, useCropDimensions: true);
|
||||
var url = mediaItem.GetCropUrl(imageUrlGenerator, propertyAlias: propertyAlias, cropAlias: cropAlias, useCropDimensions: true);
|
||||
return htmlEncode ? new HtmlString(HttpUtility.HtmlEncode(url)) : new HtmlString(url);
|
||||
}
|
||||
|
||||
@@ -133,6 +134,7 @@ namespace Umbraco.Web
|
||||
/// </returns>
|
||||
public static IHtmlString GetCropUrl(this UrlHelper urlHelper,
|
||||
IPublishedContent mediaItem,
|
||||
IImageUrlGenerator imageUrlGenerator,
|
||||
int? width = null,
|
||||
int? height = null,
|
||||
string propertyAlias = Umbraco.Core.Constants.Conventions.Media.File,
|
||||
@@ -150,7 +152,7 @@ namespace Umbraco.Web
|
||||
{
|
||||
if (mediaItem == null) return EmptyHtmlString;
|
||||
|
||||
var url = mediaItem.GetCropUrl(width, height, propertyAlias, cropAlias, quality, imageCropMode,
|
||||
var url = mediaItem.GetCropUrl(imageUrlGenerator, width, height, propertyAlias, cropAlias, quality, imageCropMode,
|
||||
imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBuster, furtherOptions, ratioMode,
|
||||
upScale);
|
||||
return htmlEncode ? new HtmlString(HttpUtility.HtmlEncode(url)) : new HtmlString(url);
|
||||
@@ -216,6 +218,7 @@ namespace Umbraco.Web
|
||||
/// </returns>
|
||||
public static IHtmlString GetCropUrl(this UrlHelper urlHelper,
|
||||
string imageUrl,
|
||||
IImageUrlGenerator imageUrlGenerator,
|
||||
int? width = null,
|
||||
int? height = null,
|
||||
string imageCropperValue = null,
|
||||
@@ -231,7 +234,7 @@ namespace Umbraco.Web
|
||||
bool upScale = true,
|
||||
bool htmlEncode = true)
|
||||
{
|
||||
var url = imageUrl.GetCropUrl(width, height, imageCropperValue, cropAlias, quality, imageCropMode,
|
||||
var url = imageUrl.GetCropUrl(imageUrlGenerator, width, height, imageCropperValue, cropAlias, quality, imageCropMode,
|
||||
imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBusterValue, furtherOptions, ratioMode,
|
||||
upScale);
|
||||
return htmlEncode ? new HtmlString(HttpUtility.HtmlEncode(url)) : new HtmlString(url);
|
||||
@@ -239,6 +242,7 @@ namespace Umbraco.Web
|
||||
|
||||
public static IHtmlString GetCropUrl(this UrlHelper urlHelper,
|
||||
ImageCropperValue imageCropperValue,
|
||||
IImageUrlGenerator imageUrlGenerator,
|
||||
int? width = null,
|
||||
int? height = null,
|
||||
string cropAlias = null,
|
||||
@@ -256,7 +260,7 @@ namespace Umbraco.Web
|
||||
if (imageCropperValue == null) return EmptyHtmlString;
|
||||
|
||||
var imageUrl = imageCropperValue.Src;
|
||||
var url = imageUrl.GetCropUrl(imageCropperValue, width, height, cropAlias, quality, imageCropMode,
|
||||
var url = imageUrl.GetCropUrl(imageUrlGenerator, imageCropperValue, width, height, cropAlias, quality, imageCropMode,
|
||||
imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBusterValue, furtherOptions, ratioMode,
|
||||
upScale);
|
||||
return htmlEncode ? new HtmlString(HttpUtility.HtmlEncode(url)) : new HtmlString(url);
|
||||
|
||||
Reference in New Issue
Block a user