Merge branch 'main' of https://github.com/umbraco/Umbraco-CMS
This commit is contained in:
@@ -40,7 +40,7 @@ public class TextStringValueConverter : PropertyValueConverterBase, IDeliveryApi
|
||||
var sourceString = source.ToString();
|
||||
|
||||
// ensures string is parsed for {localLink} and URLs are resolved correctly
|
||||
sourceString = _linkParser.EnsureInternalLinks(sourceString!, preview);
|
||||
sourceString = _linkParser.EnsureInternalLinks(sourceString!);
|
||||
sourceString = _urlParser.EnsureUrls(sourceString);
|
||||
|
||||
return sourceString;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
|
||||
namespace Umbraco.Cms.Core.Templates;
|
||||
@@ -45,17 +46,18 @@ public sealed class HtmlLocalLinkParser
|
||||
/// <summary>
|
||||
/// Parses the string looking for the {localLink} syntax and updates them to their correct links.
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <param name="preview"></param>
|
||||
/// <returns></returns>
|
||||
[Obsolete("This method overload is no longer used in Umbraco and delegates to the overload without the preview parameter. Scheduled for removal in Umbraco 18.")]
|
||||
public string EnsureInternalLinks(string text, bool preview) => EnsureInternalLinks(text);
|
||||
|
||||
/// <summary>
|
||||
/// Parses the string looking for the {localLink} syntax and updates them to their correct links.
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <returns></returns>
|
||||
public string EnsureInternalLinks(string text)
|
||||
public string EnsureInternalLinks(string text) => EnsureInternalLinks(text, UrlMode.Default);
|
||||
|
||||
/// <summary>
|
||||
/// Parses the string looking for the {localLink} syntax and updates them to their correct links.
|
||||
/// </summary>
|
||||
public string EnsureInternalLinks(string text, UrlMode urlMode)
|
||||
{
|
||||
foreach (LocalLinkTag tagData in FindLocalLinkIds(text))
|
||||
{
|
||||
@@ -63,8 +65,8 @@ public sealed class HtmlLocalLinkParser
|
||||
{
|
||||
var newLink = tagData.Udi?.EntityType switch
|
||||
{
|
||||
Constants.UdiEntityType.Document => _publishedUrlProvider.GetUrl(tagData.Udi.Guid),
|
||||
Constants.UdiEntityType.Media => _publishedUrlProvider.GetMediaUrl(tagData.Udi.Guid),
|
||||
Constants.UdiEntityType.Document => _publishedUrlProvider.GetUrl(tagData.Udi.Guid, urlMode),
|
||||
Constants.UdiEntityType.Media => _publishedUrlProvider.GetMediaUrl(tagData.Udi.Guid, urlMode),
|
||||
_ => string.Empty,
|
||||
};
|
||||
|
||||
@@ -73,7 +75,7 @@ public sealed class HtmlLocalLinkParser
|
||||
}
|
||||
else if (tagData.IntId.HasValue)
|
||||
{
|
||||
var newLink = _publishedUrlProvider.GetUrl(tagData.IntId.Value);
|
||||
var newLink = _publishedUrlProvider.GetUrl(tagData.IntId.Value, urlMode);
|
||||
text = text.Replace(tagData.TagHref, newLink);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -671,6 +671,15 @@ SELECT 4 AS [Key], COUNT(id) AS [Value] FROM umbracoUser WHERE userDisabled = 0
|
||||
|
||||
protected override void PersistDeletedItem(IUser entity)
|
||||
{
|
||||
// Clear user group caches for any user groups associated with the deleted user.
|
||||
// We need to do this because the count of the number of users in the user group is cached
|
||||
// along with the user group, and if we've made changes to the user groups assigned to the user,
|
||||
// the count for the groups need to be refreshed.
|
||||
foreach (IReadOnlyUserGroup group in entity.Groups)
|
||||
{
|
||||
ClearRepositoryCacheForUserGroup(group.Id);
|
||||
}
|
||||
|
||||
IEnumerable<string> deletes = GetDeleteClauses();
|
||||
foreach (var delete in deletes)
|
||||
{
|
||||
@@ -713,8 +722,8 @@ SELECT 4 AS [Key], COUNT(id) AS [Value] FROM umbracoUser WHERE userDisabled = 0
|
||||
if (entity.IsPropertyDirty("Groups"))
|
||||
{
|
||||
// lookup all assigned
|
||||
List<UserGroupDto>? assigned = entity.Groups == null || entity.Groups.Any() == false
|
||||
? new List<UserGroupDto>()
|
||||
List<UserGroupDto>? assigned = entity.Groups.Any() is false
|
||||
? []
|
||||
: Database.Fetch<UserGroupDto>(
|
||||
"SELECT * FROM umbracoUserGroup WHERE userGroupAlias IN (@aliases)",
|
||||
new { aliases = entity.Groups.Select(x => x.Alias) });
|
||||
@@ -724,6 +733,15 @@ SELECT 4 AS [Key], COUNT(id) AS [Value] FROM umbracoUser WHERE userDisabled = 0
|
||||
var dto = new User2UserGroupDto { UserGroupId = groupDto.Id, UserId = entity.Id };
|
||||
Database.Insert(dto);
|
||||
}
|
||||
|
||||
// Clear user group caches for the user groups associated with the new user.
|
||||
// We need to do this because the count of the number of users in the user group is cached
|
||||
// along with the user group, and if we've made changes to the user groups assigned to the user,
|
||||
// the count for the groups need to be refreshed.
|
||||
foreach (IReadOnlyUserGroup group in entity.Groups)
|
||||
{
|
||||
ClearRepositoryCacheForUserGroup(group.Id);
|
||||
}
|
||||
}
|
||||
|
||||
entity.ResetDirtyProperties();
|
||||
@@ -836,27 +854,66 @@ SELECT 4 AS [Key], COUNT(id) AS [Value] FROM umbracoUser WHERE userDisabled = 0
|
||||
|
||||
if (entity.IsPropertyDirty("Groups"))
|
||||
{
|
||||
//lookup all assigned
|
||||
List<UserGroupDto>? assigned = entity.Groups == null || entity.Groups.Any() == false
|
||||
? new List<UserGroupDto>()
|
||||
: Database.Fetch<UserGroupDto>(
|
||||
"SELECT * FROM umbracoUserGroup WHERE userGroupAlias IN (@aliases)",
|
||||
new { aliases = entity.Groups.Select(x => x.Alias) });
|
||||
// Get all user groups Ids currently assigned to the user.
|
||||
var existingUserGroupIds = Database.Fetch<User2UserGroupDto>(
|
||||
"WHERE UserId = @UserId",
|
||||
new { UserId = entity.Id })
|
||||
.Select(x => x.UserGroupId)
|
||||
.ToList();
|
||||
|
||||
//first delete all
|
||||
// TODO: We could do this a nicer way instead of "Nuke and Pave"
|
||||
Database.Delete<User2UserGroupDto>("WHERE UserId = @UserId", new { UserId = entity.Id });
|
||||
// Get the user groups Ids that need to be removed and added.
|
||||
var userGroupsIdsToRemove = existingUserGroupIds
|
||||
.Except(entity.Groups.Select(x => x.Id))
|
||||
.ToList();
|
||||
var userGroupIdsToAdd = entity.Groups
|
||||
.Select(x => x.Id)
|
||||
.Except(existingUserGroupIds)
|
||||
.ToList();
|
||||
|
||||
foreach (UserGroupDto? groupDto in assigned)
|
||||
// Remove user groups that are no longer assigned to the user.
|
||||
if (userGroupsIdsToRemove.Count > 0)
|
||||
{
|
||||
var dto = new User2UserGroupDto { UserGroupId = groupDto.Id, UserId = entity.Id };
|
||||
Database.Insert(dto);
|
||||
Database.Delete<User2UserGroupDto>(
|
||||
"WHERE UserId = @UserId AND UserGroupId IN (@userGroupIds)",
|
||||
new { UserId = entity.Id, userGroupIds = userGroupsIdsToRemove });
|
||||
}
|
||||
|
||||
// Add user groups that are newly assigned to the user.
|
||||
if (userGroupIdsToAdd.Count > 0)
|
||||
{
|
||||
IEnumerable<User2UserGroupDto> user2UserGroupDtos = userGroupIdsToAdd
|
||||
.Select(userGroupId => new User2UserGroupDto
|
||||
{
|
||||
UserGroupId = userGroupId,
|
||||
UserId = entity.Id,
|
||||
});
|
||||
Database.InsertBulk(user2UserGroupDtos);
|
||||
}
|
||||
|
||||
// Clear user group caches for any user group that have been removed or added.
|
||||
// We need to do this because the count of the number of users in the user group is cached
|
||||
// along with the user group, and if we've made changes to the user groups assigned to the user,
|
||||
// the count for the groups need to be refreshed.
|
||||
var userGroupIdsToRefresh = userGroupsIdsToRemove
|
||||
.Union(userGroupIdsToAdd)
|
||||
.ToList();
|
||||
foreach (int userGroupIdToRefresh in userGroupIdsToRefresh)
|
||||
{
|
||||
ClearRepositoryCacheForUserGroup(userGroupIdToRefresh);
|
||||
}
|
||||
}
|
||||
|
||||
entity.ResetDirtyProperties();
|
||||
}
|
||||
|
||||
private void ClearRepositoryCacheForUserGroup(int id)
|
||||
{
|
||||
IAppPolicyCache userGroupCache = AppCaches.IsolatedCaches.GetOrCreate<IUserGroup>();
|
||||
|
||||
string cacheKey = RepositoryCacheKeys.GetKey<IUserGroup, int>(id);
|
||||
userGroupCache.Clear(cacheKey);
|
||||
}
|
||||
|
||||
private void AddingOrUpdateStartNodes(IEntity entity, IEnumerable<UserStartNodeDto> current,
|
||||
UserStartNodeDto.StartNodeTypeValue startNodeType, int[]? entityStartIds)
|
||||
{
|
||||
|
||||
@@ -41,7 +41,7 @@ public class MarkdownEditorValueConverter : PropertyValueConverterBase, IDeliver
|
||||
var sourceString = source.ToString()!;
|
||||
|
||||
// ensures string is parsed for {localLink} and URLs are resolved correctly
|
||||
sourceString = _localLinkParser.EnsureInternalLinks(sourceString, preview);
|
||||
sourceString = _localLinkParser.EnsureInternalLinks(sourceString);
|
||||
sourceString = _urlParser.EnsureUrls(sourceString);
|
||||
|
||||
return sourceString;
|
||||
|
||||
@@ -135,7 +135,7 @@ public class RteBlockRenderingValueConverter : SimpleRichTextValueConverter, IDe
|
||||
var sourceString = intermediateValue.Markup;
|
||||
|
||||
// ensures string is parsed for {localLink} and URLs and media are resolved correctly
|
||||
sourceString = _linkParser.EnsureInternalLinks(sourceString, preview);
|
||||
sourceString = _linkParser.EnsureInternalLinks(sourceString);
|
||||
sourceString = _urlParser.EnsureUrls(sourceString);
|
||||
sourceString = _imageSourceParser.EnsureImageSources(sourceString);
|
||||
|
||||
|
||||
@@ -266,6 +266,15 @@ export class UmbInputTiptapElement extends UmbFormControlMixin<string, typeof Um
|
||||
max-width: var(--umb-rte-max-width, 100%);
|
||||
}
|
||||
|
||||
:host(:hover) {
|
||||
--umb-tiptap-edge-border-color: var(--uui-color-border-standalone);
|
||||
}
|
||||
|
||||
:host(:focus),
|
||||
:host(:focus-within) {
|
||||
--umb-tiptap-edge-border-color: var(--uui-color-border-emphasis);
|
||||
}
|
||||
|
||||
:host([readonly]) {
|
||||
pointer-events: none;
|
||||
|
||||
@@ -335,6 +344,12 @@ export class UmbInputTiptapElement extends UmbFormControlMixin<string, typeof Um
|
||||
}
|
||||
}
|
||||
|
||||
#editor,
|
||||
umb-tiptap-toolbar,
|
||||
umb-tiptap-statusbar {
|
||||
transition: border-color 120ms ease-out;
|
||||
}
|
||||
|
||||
umb-tiptap-toolbar + #editor {
|
||||
border-top: 0;
|
||||
border-top-left-radius: 0;
|
||||
|
||||
Reference in New Issue
Block a user