Merge remote-tracking branch 'origin/v12/dev' into v14/dev
This commit is contained in:
@@ -29,5 +29,6 @@ public static partial class Constants
|
||||
public static string DatabaseProvider = "DatabaseProvider";
|
||||
public static string CurrentServerRole = "CurrentServerRole";
|
||||
public static string RuntimeMode = "RuntimeMode";
|
||||
public static string BackofficeExternalLoginProviderCount = "BackofficeExternalLoginProviderCount";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3010,7 +3010,7 @@ To manage your website, simply open the Umbraco backoffice and start adding cont
|
||||
We will send:
|
||||
<ul>
|
||||
<li>Anonymized site ID, Umbraco version, and packages installed.</li>
|
||||
<li>Number of: Root nodes, Content nodes, Macros, Media, Document Types, Templates, Languages, Domains, User Group, Users, Members, and Property Editors in use.</li>
|
||||
<li>Number of: Root nodes, Content nodes, Macros, Media, Document Types, Templates, Languages, Domains, User Group, Users, Members, Backoffice external login providers, and Property Editors in use.</li>
|
||||
<li>System information: Webserver, server OS, server framework, server OS language, and database provider.</li>
|
||||
<li>Configuration settings: Modelsbuilder mode, if custom Umbraco path exists, ASP environment, and if you are in debug mode.</li>
|
||||
</ul>
|
||||
|
||||
@@ -10,10 +10,14 @@ namespace Umbraco.Cms.Core.PropertyEditors;
|
||||
public class DefaultPropertyIndexValueFactory : IPropertyIndexValueFactory
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<KeyValuePair<string, IEnumerable<object?>>> GetIndexValues(IProperty property, string? culture, string? segment, bool published)
|
||||
public IEnumerable<KeyValuePair<string, IEnumerable<object?>>> GetIndexValues(IProperty property, string? culture, string? segment, bool published, IEnumerable<string> availableCultures)
|
||||
{
|
||||
yield return new KeyValuePair<string, IEnumerable<object?>>(
|
||||
property.Alias,
|
||||
property.GetValue(culture, segment, published).Yield());
|
||||
}
|
||||
|
||||
[Obsolete("Use the overload with the availableCultures parameter instead, scheduled for removal in v14")]
|
||||
public IEnumerable<KeyValuePair<string, IEnumerable<object?>>> GetIndexValues(IProperty property, string? culture, string? segment, bool published)
|
||||
=> GetIndexValues(property, culture, segment, published, Enumerable.Empty<string>());
|
||||
}
|
||||
|
||||
@@ -22,5 +22,9 @@ public interface IPropertyIndexValueFactory
|
||||
/// more than one value for a given field.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
IEnumerable<KeyValuePair<string, IEnumerable<object?>>> GetIndexValues(IProperty property, string? culture, string? segment, bool published, IEnumerable<string> availableCultures)
|
||||
=> GetIndexValues(property, culture, segment, published);
|
||||
|
||||
[Obsolete("Use the overload with the availableCultures parameter instead, scheduled for removal in v14")]
|
||||
IEnumerable<KeyValuePair<string, IEnumerable<object?>>> GetIndexValues(IProperty property, string? culture, string? segment, bool published);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,8 @@ public abstract class JsonPropertyIndexValueFactoryBase<TSerialized> : IProperty
|
||||
IProperty property,
|
||||
string? culture,
|
||||
string? segment,
|
||||
bool published)
|
||||
bool published,
|
||||
IEnumerable<string> availableCultures)
|
||||
{
|
||||
var result = new List<KeyValuePair<string, IEnumerable<object?>>>();
|
||||
|
||||
@@ -43,7 +44,7 @@ public abstract class JsonPropertyIndexValueFactoryBase<TSerialized> : IProperty
|
||||
return result;
|
||||
}
|
||||
|
||||
result.AddRange(Handle(deserializedPropertyValue, property, culture, segment, published));
|
||||
result.AddRange(Handle(deserializedPropertyValue, property, culture, segment, published, availableCultures));
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
@@ -62,6 +63,10 @@ public abstract class JsonPropertyIndexValueFactoryBase<TSerialized> : IProperty
|
||||
return result;
|
||||
}
|
||||
|
||||
[Obsolete("Use method overload that has availableCultures, scheduled for removal in v14")]
|
||||
public IEnumerable<KeyValuePair<string, IEnumerable<object?>>> GetIndexValues(IProperty property, string? culture, string? segment, bool published)
|
||||
=> GetIndexValues(property, culture, segment, published, Enumerable.Empty<string>());
|
||||
|
||||
/// <summary>
|
||||
/// Method to return a list of resume of the content. By default this returns an empty list
|
||||
/// </summary>
|
||||
@@ -75,10 +80,23 @@ public abstract class JsonPropertyIndexValueFactoryBase<TSerialized> : IProperty
|
||||
/// <summary>
|
||||
/// Method that handle the deserialized object.
|
||||
/// </summary>
|
||||
[Obsolete("Use the overload with the availableCultures parameter instead, scheduled for removal in v14")]
|
||||
protected abstract IEnumerable<KeyValuePair<string, IEnumerable<object?>>> Handle(
|
||||
TSerialized deserializedPropertyValue,
|
||||
IProperty property,
|
||||
string? culture,
|
||||
string? segment,
|
||||
bool published);
|
||||
|
||||
/// <summary>
|
||||
/// Method that handle the deserialized object.
|
||||
/// </summary>
|
||||
protected virtual IEnumerable<KeyValuePair<string, IEnumerable<object?>>> Handle(
|
||||
TSerialized deserializedPropertyValue,
|
||||
IProperty property,
|
||||
string? culture,
|
||||
string? segment,
|
||||
bool published,
|
||||
IEnumerable<string> availableCultures) =>
|
||||
Handle(deserializedPropertyValue, property, culture, segment, published);
|
||||
}
|
||||
|
||||
@@ -8,5 +8,9 @@ namespace Umbraco.Cms.Core.PropertyEditors;
|
||||
public class NoopPropertyIndexValueFactory : IPropertyIndexValueFactory
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<KeyValuePair<string, IEnumerable<object?>>> GetIndexValues(IProperty property, string? culture, string? segment, bool published) => Array.Empty<KeyValuePair<string, IEnumerable<object?>>>();
|
||||
public IEnumerable<KeyValuePair<string, IEnumerable<object?>>> GetIndexValues(IProperty property, string? culture, string? segment, bool published, IEnumerable<string> availableCultures) => Array.Empty<KeyValuePair<string, IEnumerable<object?>>>();
|
||||
|
||||
[Obsolete("Use the overload with the availableCultures parameter instead, scheduled for removal in v14")]
|
||||
public IEnumerable<KeyValuePair<string, IEnumerable<object?>>> GetIndexValues(IProperty property, string? culture, string? segment, bool published)
|
||||
=> GetIndexValues(property, culture, segment, published);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,18 @@ public class TagPropertyIndexValueFactory : JsonPropertyIndexValueFactoryBase<st
|
||||
{
|
||||
}
|
||||
|
||||
protected override IEnumerable<KeyValuePair<string, IEnumerable<object?>>> Handle(
|
||||
string[] deserializedPropertyValue,
|
||||
IProperty property,
|
||||
string? culture,
|
||||
string? segment,
|
||||
bool published,
|
||||
IEnumerable<string> availableCultures)
|
||||
{
|
||||
yield return new KeyValuePair<string, IEnumerable<object?>>(property.Alias, deserializedPropertyValue);
|
||||
}
|
||||
|
||||
[Obsolete("Use the overload that specifies availableCultures, scheduled for removal in v14")]
|
||||
protected override IEnumerable<KeyValuePair<string, IEnumerable<object?>>> Handle(
|
||||
string[] deserializedPropertyValue,
|
||||
IProperty property,
|
||||
|
||||
@@ -39,7 +39,8 @@ public static partial class UmbracoBuilderExtensions
|
||||
factory.GetRequiredService<IUserService>(),
|
||||
factory.GetRequiredService<IShortStringHelper>(),
|
||||
factory.GetRequiredService<IScopeProvider>(),
|
||||
true));
|
||||
true,
|
||||
factory.GetRequiredService<ILocalizationService>()));
|
||||
builder.Services.AddUnique<IContentValueSetBuilder>(factory =>
|
||||
new ContentValueSetBuilder(
|
||||
factory.GetRequiredService<PropertyEditorCollection>(),
|
||||
@@ -47,7 +48,8 @@ public static partial class UmbracoBuilderExtensions
|
||||
factory.GetRequiredService<IUserService>(),
|
||||
factory.GetRequiredService<IShortStringHelper>(),
|
||||
factory.GetRequiredService<IScopeProvider>(),
|
||||
false));
|
||||
false,
|
||||
factory.GetRequiredService<ILocalizationService>()));
|
||||
builder.Services.AddUnique<IValueSetBuilder<IMedia>, MediaValueSetBuilder>();
|
||||
builder.Services.AddUnique<IValueSetBuilder<IMember>, MemberValueSetBuilder>();
|
||||
builder.Services.AddUnique<IDeliveryApiContentIndexValueSetBuilder, DeliveryApiContentIndexValueSetBuilder>();
|
||||
|
||||
@@ -22,7 +22,11 @@ public abstract class BaseValueSetBuilder<TContent> : IValueSetBuilder<TContent>
|
||||
/// <inheritdoc />
|
||||
public abstract IEnumerable<ValueSet> GetValueSets(params TContent[] content);
|
||||
|
||||
[Obsolete("Use the overload that specifies availableCultures, scheduled for removal in v14")]
|
||||
protected void AddPropertyValue(IProperty property, string? culture, string? segment, IDictionary<string, IEnumerable<object?>>? values)
|
||||
=> AddPropertyValue(property, culture, segment, values, Enumerable.Empty<string>());
|
||||
|
||||
protected void AddPropertyValue(IProperty property, string? culture, string? segment, IDictionary<string, IEnumerable<object?>>? values, IEnumerable<string> availableCultures)
|
||||
{
|
||||
IDataEditor? editor = _propertyEditors[property.PropertyType.PropertyEditorAlias];
|
||||
if (editor == null)
|
||||
@@ -31,7 +35,7 @@ public abstract class BaseValueSetBuilder<TContent> : IValueSetBuilder<TContent>
|
||||
}
|
||||
|
||||
IEnumerable<KeyValuePair<string, IEnumerable<object?>>> indexVals =
|
||||
editor.PropertyIndexValueFactory.GetIndexValues(property, culture, segment, PublishedValuesOnly);
|
||||
editor.PropertyIndexValueFactory.GetIndexValues(property, culture, segment, PublishedValuesOnly, availableCultures);
|
||||
foreach (KeyValuePair<string, IEnumerable<object?>> keyVal in indexVals)
|
||||
{
|
||||
if (keyVal.Key.IsNullOrWhiteSpace())
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using Examine;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.Membership;
|
||||
using Umbraco.Cms.Core.PropertyEditors;
|
||||
using Umbraco.Cms.Core.Scoping;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Strings;
|
||||
using Umbraco.Cms.Web.Common.DependencyInjection;
|
||||
using Umbraco.Extensions;
|
||||
using IScope = Umbraco.Cms.Infrastructure.Scoping.IScope;
|
||||
|
||||
@@ -24,6 +26,7 @@ public class ContentValueSetBuilder : BaseValueSetBuilder<IContent>, IContentVal
|
||||
private readonly IShortStringHelper _shortStringHelper;
|
||||
private readonly UrlSegmentProviderCollection _urlSegmentProviders;
|
||||
private readonly IUserService _userService;
|
||||
private readonly ILocalizationService _localizationService;
|
||||
|
||||
public ContentValueSetBuilder(
|
||||
PropertyEditorCollection propertyEditors,
|
||||
@@ -31,13 +34,34 @@ public class ContentValueSetBuilder : BaseValueSetBuilder<IContent>, IContentVal
|
||||
IUserService userService,
|
||||
IShortStringHelper shortStringHelper,
|
||||
IScopeProvider scopeProvider,
|
||||
bool publishedValuesOnly)
|
||||
bool publishedValuesOnly,
|
||||
ILocalizationService localizationService)
|
||||
: base(propertyEditors, publishedValuesOnly)
|
||||
{
|
||||
_urlSegmentProviders = urlSegmentProviders;
|
||||
_userService = userService;
|
||||
_shortStringHelper = shortStringHelper;
|
||||
_scopeProvider = scopeProvider;
|
||||
_localizationService = localizationService;
|
||||
}
|
||||
|
||||
[Obsolete("Use the constructor that takes an ILocalizationService, scheduled for removal in v14")]
|
||||
public ContentValueSetBuilder(
|
||||
PropertyEditorCollection propertyEditors,
|
||||
UrlSegmentProviderCollection urlSegmentProviders,
|
||||
IUserService userService,
|
||||
IShortStringHelper shortStringHelper,
|
||||
IScopeProvider scopeProvider,
|
||||
bool publishedValuesOnly)
|
||||
: this(
|
||||
propertyEditors,
|
||||
urlSegmentProviders,
|
||||
userService,
|
||||
shortStringHelper,
|
||||
scopeProvider,
|
||||
publishedValuesOnly,
|
||||
StaticServiceProvider.Instance.GetRequiredService<ILocalizationService>())
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -128,17 +152,23 @@ public class ContentValueSetBuilder : BaseValueSetBuilder<IContent>, IContentVal
|
||||
}
|
||||
}
|
||||
|
||||
var availableCultures = new List<string>(c.AvailableCultures);
|
||||
if (availableCultures.Any() is false)
|
||||
{
|
||||
availableCultures.Add(_localizationService.GetDefaultLanguageIsoCode());
|
||||
}
|
||||
|
||||
foreach (IProperty property in c.Properties)
|
||||
{
|
||||
if (!property.PropertyType.VariesByCulture())
|
||||
{
|
||||
AddPropertyValue(property, null, null, values);
|
||||
AddPropertyValue(property, null, null, values, availableCultures);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var culture in c.AvailableCultures)
|
||||
{
|
||||
AddPropertyValue(property, culture.ToLowerInvariant(), null, values);
|
||||
AddPropertyValue(property, culture.ToLowerInvariant(), null, values, availableCultures);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ public class MediaValueSetBuilder : BaseValueSetBuilder<IMedia>
|
||||
|
||||
foreach (IProperty property in m.Properties)
|
||||
{
|
||||
AddPropertyValue(property, null, null, values);
|
||||
AddPropertyValue(property, null, null, values, m.AvailableCultures);
|
||||
}
|
||||
|
||||
var vs = new ValueSet(m.Id.ToInvariantString(), IndexTypes.Media, m.ContentType.Alias, values);
|
||||
|
||||
@@ -37,7 +37,7 @@ public class MemberValueSetBuilder : BaseValueSetBuilder<IMember>
|
||||
|
||||
foreach (IProperty property in m.Properties)
|
||||
{
|
||||
AddPropertyValue(property, null, null, values);
|
||||
AddPropertyValue(property, null, null, values, m.AvailableCultures);
|
||||
}
|
||||
|
||||
var vs = new ValueSet(m.Id.ToInvariantString(), IndexTypes.Member, m.ContentType.Alias, values);
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Umbraco.Cms.Core.PropertyEditors
|
||||
[Obsolete("The grid is obsolete, will be removed in V13")]
|
||||
public class GridPropertyIndexValueFactory : IPropertyIndexValueFactory
|
||||
{
|
||||
public IEnumerable<KeyValuePair<string, IEnumerable<object?>>> GetIndexValues(IProperty property, string? culture, string? segment, bool published)
|
||||
public IEnumerable<KeyValuePair<string, IEnumerable<object?>>> GetIndexValues(IProperty property, string? culture, string? segment, bool published, IEnumerable<string> availableCultures)
|
||||
{
|
||||
var result = new List<KeyValuePair<string, IEnumerable<object?>>>();
|
||||
|
||||
@@ -89,5 +89,9 @@ namespace Umbraco.Cms.Core.PropertyEditors
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[Obsolete("Use the overload that specifies availableCultures, scheduled for removal in v14")]
|
||||
public IEnumerable<KeyValuePair<string, IEnumerable<object?>>> GetIndexValues(IProperty property, string? culture, string? segment, bool published)
|
||||
=> GetIndexValues(property, culture, segment, published);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,15 +18,26 @@ internal abstract class NestedPropertyIndexValueFactoryBase<TSerialized, TItem>
|
||||
_propertyEditorCollection = propertyEditorCollection;
|
||||
}
|
||||
|
||||
[Obsolete("Use the overload that specifies availableCultures, scheduled for removal in v14")]
|
||||
protected override IEnumerable<KeyValuePair<string, IEnumerable<object?>>> Handle(
|
||||
TSerialized deserializedPropertyValue,
|
||||
IProperty property,
|
||||
string? culture,
|
||||
string? segment,
|
||||
bool published)
|
||||
bool published) =>
|
||||
Handle(deserializedPropertyValue, property, culture, segment, published, Enumerable.Empty<string>());
|
||||
|
||||
protected override IEnumerable<KeyValuePair<string, IEnumerable<object?>>> Handle(
|
||||
TSerialized deserializedPropertyValue,
|
||||
IProperty property,
|
||||
string? culture,
|
||||
string? segment,
|
||||
bool published,
|
||||
IEnumerable<string> availableCultures)
|
||||
{
|
||||
var result = new List<KeyValuePair<string, IEnumerable<object?>>>();
|
||||
|
||||
var index = 0;
|
||||
foreach (TItem nestedContentRowValue in GetDataItems(deserializedPropertyValue))
|
||||
{
|
||||
IContentType? contentType = GetContentTypeOfNestedItem(nestedContentRowValue);
|
||||
@@ -60,12 +71,15 @@ internal abstract class NestedPropertyIndexValueFactoryBase<TSerialized, TItem>
|
||||
.ToDictionary(x => x.Alias);
|
||||
|
||||
result.AddRange(GetNestedResults(
|
||||
property.Alias,
|
||||
$"{property.Alias}.items[{index}]",
|
||||
culture,
|
||||
segment,
|
||||
published,
|
||||
propertyTypeDictionary,
|
||||
nestedContentRowValue));
|
||||
nestedContentRowValue,
|
||||
availableCultures));
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
return RenameKeysToEnsureRawSegmentsIsAPrefix(result);
|
||||
@@ -160,39 +174,51 @@ internal abstract class NestedPropertyIndexValueFactoryBase<TSerialized, TItem>
|
||||
string? segment,
|
||||
bool published,
|
||||
IDictionary<string, IPropertyType> propertyTypeDictionary,
|
||||
TItem nestedContentRowValue)
|
||||
TItem nestedContentRowValue,
|
||||
IEnumerable<string> availableCultures)
|
||||
{
|
||||
var blockIndex = 0;
|
||||
|
||||
foreach ((var propertyAlias, var propertyValue) in GetRawProperty(nestedContentRowValue))
|
||||
{
|
||||
if (propertyTypeDictionary.TryGetValue(propertyAlias, out IPropertyType? propertyType))
|
||||
{
|
||||
IProperty subProperty = new Property(propertyType);
|
||||
subProperty.SetValue(propertyValue, culture, segment);
|
||||
|
||||
if (published)
|
||||
{
|
||||
subProperty.PublishValues(culture, segment ?? "*");
|
||||
}
|
||||
|
||||
IDataEditor? editor = _propertyEditorCollection[propertyType.PropertyEditorAlias];
|
||||
if (editor is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IEnumerable<KeyValuePair<string, IEnumerable<object?>>> indexValues =
|
||||
editor.PropertyIndexValueFactory.GetIndexValues(subProperty, culture, segment, published);
|
||||
IProperty subProperty = new Property(propertyType);
|
||||
IEnumerable<KeyValuePair<string, IEnumerable<object?>>> indexValues = null!;
|
||||
|
||||
if (propertyType.VariesByCulture() && culture is null)
|
||||
{
|
||||
foreach (var availableCulture in availableCultures)
|
||||
{
|
||||
subProperty.SetValue(propertyValue, availableCulture, segment);
|
||||
if (published)
|
||||
{
|
||||
subProperty.PublishValues(availableCulture, segment ?? "*");
|
||||
}
|
||||
indexValues =
|
||||
editor.PropertyIndexValueFactory.GetIndexValues(subProperty, availableCulture, segment, published, availableCultures);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
subProperty.SetValue(propertyValue, culture, segment);
|
||||
if (published)
|
||||
{
|
||||
subProperty.PublishValues(culture ?? "*", segment ?? "*");
|
||||
}
|
||||
indexValues = editor.PropertyIndexValueFactory.GetIndexValues(subProperty, culture, segment, published, availableCultures);
|
||||
}
|
||||
|
||||
foreach ((var nestedAlias, IEnumerable<object?> nestedValue) in indexValues)
|
||||
{
|
||||
yield return new KeyValuePair<string, IEnumerable<object?>>(
|
||||
$"{keyPrefix}.items[{blockIndex}].{nestedAlias}", nestedValue!);
|
||||
$"{keyPrefix}.{nestedAlias}", nestedValue!);
|
||||
}
|
||||
}
|
||||
|
||||
blockIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,7 +307,7 @@ public class RichTextPropertyEditor : DataEditor
|
||||
|
||||
internal class RichTextPropertyIndexValueFactory : IPropertyIndexValueFactory
|
||||
{
|
||||
public IEnumerable<KeyValuePair<string, IEnumerable<object?>>> GetIndexValues(IProperty property, string? culture, string? segment, bool published)
|
||||
public IEnumerable<KeyValuePair<string, IEnumerable<object?>>> GetIndexValues(IProperty property, string? culture, string? segment, bool published, IEnumerable<string> availableCultures)
|
||||
{
|
||||
var val = property.GetValue(culture, segment, published);
|
||||
|
||||
@@ -325,5 +325,9 @@ public class RichTextPropertyEditor : DataEditor
|
||||
yield return new KeyValuePair<string, IEnumerable<object?>>(
|
||||
$"{UmbracoExamineFieldNames.RawFieldPrefix}{property.Alias}", new object[] { strVal });
|
||||
}
|
||||
|
||||
[Obsolete("Use the overload with the 'availableCultures' parameter instead, scheduled for removal in v14")]
|
||||
public IEnumerable<KeyValuePair<string, IEnumerable<object?>>> GetIndexValues(IProperty property, string? culture, string? segment, bool published)
|
||||
=> GetIndexValues(property, culture, segment, published);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ using Umbraco.Cms.Core.Models;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.Telemetry.Interfaces;
|
||||
|
||||
internal interface IDetailedTelemetryProvider
|
||||
public interface IDetailedTelemetryProvider
|
||||
{
|
||||
IEnumerable<UsageInformation> GetInformation();
|
||||
}
|
||||
|
||||
@@ -26,6 +26,19 @@ public class TinyMceController : UmbracoAuthorizedApiController
|
||||
private readonly IIOHelper _ioHelper;
|
||||
private readonly IShortStringHelper _shortStringHelper;
|
||||
|
||||
private readonly Dictionary<string, string> _fileContentTypeMappings =
|
||||
new()
|
||||
{
|
||||
{ "image/png", "png" },
|
||||
{ "image/jpeg", "jpg" },
|
||||
{ "image/gif", "gif" },
|
||||
{ "image/bmp", "bmp" },
|
||||
{ "image/x-icon", "ico" },
|
||||
{ "image/svg+xml", "svg" },
|
||||
{ "image/tiff", "tiff" },
|
||||
{ "image/webp", "webp" },
|
||||
};
|
||||
|
||||
public TinyMceController(
|
||||
IHostingEnvironment hostingEnvironment,
|
||||
IShortStringHelper shortStringHelper,
|
||||
@@ -43,16 +56,6 @@ public class TinyMceController : UmbracoAuthorizedApiController
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> UploadImage(List<IFormFile> file)
|
||||
{
|
||||
// Create an unique folder path to help with concurrent users to avoid filename clash
|
||||
var imageTempPath =
|
||||
_hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.TempImageUploads + "/" + Guid.NewGuid());
|
||||
|
||||
// Ensure image temp path exists
|
||||
if (Directory.Exists(imageTempPath) == false)
|
||||
{
|
||||
Directory.CreateDirectory(imageTempPath);
|
||||
}
|
||||
|
||||
// Must have a file
|
||||
if (file.Count == 0)
|
||||
{
|
||||
@@ -65,13 +68,36 @@ public class TinyMceController : UmbracoAuthorizedApiController
|
||||
return new UmbracoProblemResult("Only one file can be uploaded at a time", HttpStatusCode.BadRequest);
|
||||
}
|
||||
|
||||
// Create an unique folder path to help with concurrent users to avoid filename clash
|
||||
var imageTempPath =
|
||||
_hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.TempImageUploads + "/" + Guid.NewGuid());
|
||||
|
||||
// Ensure image temp path exists
|
||||
if (Directory.Exists(imageTempPath) == false)
|
||||
{
|
||||
Directory.CreateDirectory(imageTempPath);
|
||||
}
|
||||
|
||||
IFormFile formFile = file.First();
|
||||
|
||||
// Really we should only have one file per request to this endpoint
|
||||
// var file = result.FileData[0];
|
||||
var fileName = formFile.FileName.Trim(new[] { '\"' }).TrimEnd();
|
||||
var fileName = formFile.FileName.Trim(new[] {'\"'}).TrimEnd();
|
||||
var safeFileName = fileName.ToSafeFileName(_shortStringHelper);
|
||||
var ext = safeFileName.Substring(safeFileName.LastIndexOf('.') + 1).ToLowerInvariant();
|
||||
string ext;
|
||||
var fileExtensionIndex = safeFileName.LastIndexOf('.');
|
||||
if (fileExtensionIndex is not -1)
|
||||
{
|
||||
ext = safeFileName.Substring(fileExtensionIndex + 1).ToLowerInvariant();
|
||||
}
|
||||
else
|
||||
{
|
||||
_fileContentTypeMappings.TryGetValue(formFile.ContentType, out var fileExtension);
|
||||
ext = fileExtension ?? string.Empty;
|
||||
|
||||
// safeFileName will not have a file extension, so we need to add it back
|
||||
safeFileName += $".{ext}";
|
||||
}
|
||||
|
||||
if (_contentSettings.IsFileAllowedForUpload(ext) == false ||
|
||||
_imageUrlGenerator.IsSupportedImageFormat(ext) == false)
|
||||
|
||||
@@ -14,7 +14,9 @@ using Umbraco.Cms.Core.Scoping;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.Security;
|
||||
using Umbraco.Cms.Infrastructure.Telemetry.Interfaces;
|
||||
using Umbraco.Cms.Web.BackOffice.Security;
|
||||
using Umbraco.Cms.Web.BackOffice.Telemetry;
|
||||
using Umbraco.Cms.Web.Common.AspNetCore;
|
||||
using Umbraco.Cms.Web.Common.Security;
|
||||
|
||||
@@ -79,6 +81,7 @@ public static partial class UmbracoBuilderExtensions
|
||||
// We need to know in the core services if local logins is denied, so we register the providers with a core friendly interface.
|
||||
services.TryAddSingleton<ILocalLoginSettingProvider, BackOfficeExternalLoginProviders>();
|
||||
services.TryAddSingleton<IBackOfficeTwoFactorOptions, DefaultBackOfficeTwoFactorOptions>();
|
||||
services.AddTransient<IDetailedTelemetryProvider, ExternalLoginTelemetryProvider>();
|
||||
|
||||
return new BackOfficeIdentityBuilder(services);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Infrastructure.Telemetry.Interfaces;
|
||||
using Umbraco.Cms.Web.BackOffice.Security;
|
||||
|
||||
namespace Umbraco.Cms.Web.BackOffice.Telemetry;
|
||||
|
||||
public class ExternalLoginTelemetryProvider : IDetailedTelemetryProvider
|
||||
{
|
||||
private readonly IBackOfficeExternalLoginProviders _externalLoginProviders;
|
||||
|
||||
public ExternalLoginTelemetryProvider(IBackOfficeExternalLoginProviders externalLoginProviders)
|
||||
{
|
||||
_externalLoginProviders = externalLoginProviders;
|
||||
}
|
||||
|
||||
public IEnumerable<UsageInformation> GetInformation()
|
||||
{
|
||||
IEnumerable<BackOfficeExternaLoginProviderScheme> providers = _externalLoginProviders.GetBackOfficeProvidersAsync().GetAwaiter().GetResult();
|
||||
yield return new UsageInformation(Constants.Telemetry.BackofficeExternalLoginProviderCount, providers.Count());
|
||||
}
|
||||
}
|
||||
@@ -1011,7 +1011,7 @@
|
||||
blockObject = vm.layout[createIndex].$block;
|
||||
}
|
||||
// edit block if not `hideContentInOverlay` and there is content properties.
|
||||
if(blockObject.hideContentInOverlay !== true && blockObject.content.variants[0].tabs[0]?.properties.length > 0) {
|
||||
if(blockObject.hideContentInOverlay !== true && blockObject.content.variants[0].tabs.find(tab => tab.properties.length > 0) !== undefined) {
|
||||
vm.options.createFlow = true;
|
||||
blockObject.edit();
|
||||
vm.options.createFlow = false;
|
||||
|
||||
@@ -621,7 +621,7 @@
|
||||
var blockObject = vm.layout[createIndex].$block;
|
||||
if (inlineEditing === true) {
|
||||
blockObject.activate();
|
||||
} else if (inlineEditing === false && blockObject.hideContentInOverlay !== true && blockObject.content.variants[0].tabs[0]?.properties.length > 0) {
|
||||
} else if (inlineEditing === false && blockObject.hideContentInOverlay !== true && blockObject.content.variants[0].tabs.find(tab => tab.properties.length > 0) !== undefined) {
|
||||
vm.options.createFlow = true;
|
||||
blockObject.edit();
|
||||
vm.options.createFlow = false;
|
||||
|
||||
@@ -49,7 +49,8 @@ public class TelemetryServiceTests : UmbracoIntegrationTest
|
||||
Constants.Telemetry.IsDebug,
|
||||
Constants.Telemetry.DatabaseProvider,
|
||||
Constants.Telemetry.CurrentServerRole,
|
||||
Constants.Telemetry.RuntimeMode,
|
||||
Constants.Telemetry.BackofficeExternalLoginProviderCount,
|
||||
Constants.Telemetry.RuntimeMode
|
||||
};
|
||||
|
||||
MetricsConsentService.SetConsentLevel(TelemetryLevel.Detailed);
|
||||
|
||||
@@ -3,6 +3,7 @@ using Examine.Lucene;
|
||||
using Examine.Lucene.Directories;
|
||||
using Lucene.Net.Analysis;
|
||||
using Lucene.Net.Analysis.Standard;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
@@ -18,7 +19,9 @@ using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Strings;
|
||||
using Umbraco.Cms.Infrastructure.Examine;
|
||||
using Umbraco.Cms.Infrastructure.Persistence;
|
||||
using Umbraco.Cms.Web.Common.DependencyInjection;
|
||||
using Directory = Lucene.Net.Store.Directory;
|
||||
using StaticServiceProvider = Umbraco.Cms.Core.DependencyInjection.StaticServiceProvider;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.Umbraco.Examine.Lucene.UmbracoExamine;
|
||||
|
||||
@@ -28,6 +31,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Examine.Lucene.UmbracoExamine;
|
||||
public class IndexInitializer
|
||||
{
|
||||
private readonly IOptions<ContentSettings> _contentSettings;
|
||||
private readonly ILocalizationService _localizationService;
|
||||
private readonly ILoggerFactory _loggerFactory;
|
||||
private readonly MediaUrlGeneratorCollection _mediaUrlGenerators;
|
||||
private readonly PropertyEditorCollection _propertyEditors;
|
||||
@@ -40,7 +44,8 @@ public class IndexInitializer
|
||||
MediaUrlGeneratorCollection mediaUrlGenerators,
|
||||
IScopeProvider scopeProvider,
|
||||
ILoggerFactory loggerFactory,
|
||||
IOptions<ContentSettings> contentSettings)
|
||||
IOptions<ContentSettings> contentSettings,
|
||||
ILocalizationService localizationService)
|
||||
{
|
||||
_shortStringHelper = shortStringHelper;
|
||||
_propertyEditors = propertyEditors;
|
||||
@@ -48,6 +53,25 @@ public class IndexInitializer
|
||||
_scopeProvider = scopeProvider;
|
||||
_loggerFactory = loggerFactory;
|
||||
_contentSettings = contentSettings;
|
||||
_localizationService = localizationService;
|
||||
}
|
||||
|
||||
public IndexInitializer(
|
||||
IShortStringHelper shortStringHelper,
|
||||
PropertyEditorCollection propertyEditors,
|
||||
MediaUrlGeneratorCollection mediaUrlGenerators,
|
||||
IScopeProvider scopeProvider,
|
||||
ILoggerFactory loggerFactory,
|
||||
IOptions<ContentSettings> contentSettings)
|
||||
: this(
|
||||
shortStringHelper,
|
||||
propertyEditors,
|
||||
mediaUrlGenerators,
|
||||
scopeProvider,
|
||||
loggerFactory,
|
||||
contentSettings,
|
||||
StaticServiceProvider.Instance.GetRequiredService<ILocalizationService>())
|
||||
{
|
||||
}
|
||||
|
||||
public ContentValueSetBuilder GetContentValueSetBuilder(bool publishedValuesOnly)
|
||||
@@ -58,7 +82,8 @@ public class IndexInitializer
|
||||
GetMockUserService(),
|
||||
_shortStringHelper,
|
||||
_scopeProvider,
|
||||
publishedValuesOnly);
|
||||
publishedValuesOnly,
|
||||
_localizationService);
|
||||
|
||||
return contentValueSetBuilder;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Infrastructure.Examine;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Testing;
|
||||
using Umbraco.Extensions;
|
||||
using Constants = Umbraco.Cms.Core.Constants;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.Umbraco.Examine.Lucene.UmbracoExamine;
|
||||
@@ -18,7 +17,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Examine.Lucene.UmbracoExamine;
|
||||
/// Tests the standard indexing capabilities
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.None)]
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)]
|
||||
public class IndexTest : ExamineBaseTest
|
||||
{
|
||||
[Test]
|
||||
|
||||
Reference in New Issue
Block a user