From 13f7ee8a5fff4c3e584cb8d4405e8ac12060ed8d Mon Sep 17 00:00:00 2001
From: Shannon
Date: Mon, 21 Oct 2019 19:40:06 +1100
Subject: [PATCH 01/15] Adds IDataValueReference
---
.../PropertyEditors/IDataValueEditor.cs | 19 +++++++++++++++++++
.../PropertyEditors/IDataValueReference.cs | 17 +++++++++++++++++
src/Umbraco.Core/Umbraco.Core.csproj | 1 +
3 files changed, 37 insertions(+)
create mode 100644 src/Umbraco.Core/PropertyEditors/IDataValueReference.cs
diff --git a/src/Umbraco.Core/PropertyEditors/IDataValueEditor.cs b/src/Umbraco.Core/PropertyEditors/IDataValueEditor.cs
index cb68531cc705..a02fa71ec709 100644
--- a/src/Umbraco.Core/PropertyEditors/IDataValueEditor.cs
+++ b/src/Umbraco.Core/PropertyEditors/IDataValueEditor.cs
@@ -7,6 +7,7 @@
namespace Umbraco.Core.PropertyEditors
{
+
///
/// Represents an editor for editing data values.
///
@@ -63,8 +64,26 @@ public interface IDataValueEditor
// TODO: / deal with this when unplugging the xml cache
// why property vs propertyType? services should be injected! etc...
+
+ ///
+ /// Used for serializing an item for packaging
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
IEnumerable ConvertDbToXml(Property property, IDataTypeService dataTypeService, ILocalizationService localizationService, bool published);
+
+ ///
+ /// Used for serializing an item for packaging
+ ///
+ ///
+ ///
+ ///
+ ///
XNode ConvertDbToXml(PropertyType propertyType, object value, IDataTypeService dataTypeService);
+
string ConvertDbToString(PropertyType propertyType, object value, IDataTypeService dataTypeService);
}
}
diff --git a/src/Umbraco.Core/PropertyEditors/IDataValueReference.cs b/src/Umbraco.Core/PropertyEditors/IDataValueReference.cs
new file mode 100644
index 000000000000..d7d848f1bfe1
--- /dev/null
+++ b/src/Umbraco.Core/PropertyEditors/IDataValueReference.cs
@@ -0,0 +1,17 @@
+using System.Collections.Generic;
+
+namespace Umbraco.Core.PropertyEditors
+{
+ ///
+ /// Used to resolve references from values
+ ///
+ public interface IDataValueReference
+ {
+ ///
+ /// Returns any references contained in the value
+ ///
+ ///
+ ///
+ IEnumerable GetReferences(object value);
+ }
+}
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 43d168f442b7..be1686df4fe2 100755
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -270,6 +270,7 @@
+
From a7dfba58d10c6f91a5a59ac7e1969ac1ea1abbfc Mon Sep 17 00:00:00 2001
From: Shannon
Date: Mon, 21 Oct 2019 22:49:39 +1100
Subject: [PATCH 02/15] Removes singleton accessors from repositories
---
.../Repositories/Implement/ContentRepositoryBase.cs | 5 +++--
.../Implement/DocumentBlueprintRepository.cs | 5 +++--
.../Repositories/Implement/DocumentRepository.cs | 5 +++--
.../Repositories/Implement/MediaRepository.cs | 5 +++--
.../Repositories/Implement/MemberRepository.cs | 5 +++--
.../Repositories/ContentTypeRepositoryTest.cs | 3 ++-
.../Persistence/Repositories/DocumentRepositoryTest.cs | 2 +-
.../Persistence/Repositories/DomainRepositoryTest.cs | 5 +++--
.../Persistence/Repositories/MediaRepositoryTest.cs | 5 +++--
.../Persistence/Repositories/MemberRepositoryTest.cs | 3 ++-
.../Repositories/PublicAccessRepositoryTest.cs | 5 +++--
.../Persistence/Repositories/TagRepositoryTest.cs | 7 ++++---
.../Persistence/Repositories/TemplateRepositoryTest.cs | 3 ++-
.../Persistence/Repositories/UserRepositoryTest.cs | 5 +++--
.../Services/ContentServicePerformanceTest.cs | 9 +++++----
src/Umbraco.Tests/Services/ContentServiceTests.cs | 2 +-
16 files changed, 44 insertions(+), 30 deletions(-)
diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs
index 7ab73f3f2d51..a6ae2fc7e096 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs
@@ -33,17 +33,18 @@ internal abstract class ContentRepositoryBase : NPoco
where TEntity : class, IUmbracoEntity
where TRepository : class, IRepository
{
- protected ContentRepositoryBase(IScopeAccessor scopeAccessor, AppCaches cache, ILanguageRepository languageRepository, ILogger logger)
+ protected ContentRepositoryBase(IScopeAccessor scopeAccessor, AppCaches cache, ILanguageRepository languageRepository, ILogger logger, PropertyEditorCollection propertyEditors)
: base(scopeAccessor, cache, logger)
{
LanguageRepository = languageRepository;
+ PropertyEditors = propertyEditors;
}
protected abstract TRepository This { get; }
protected ILanguageRepository LanguageRepository { get; }
- protected PropertyEditorCollection PropertyEditors => Current.PropertyEditors; // TODO: inject
+ protected PropertyEditorCollection PropertyEditors { get; }
#region Versions
diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentBlueprintRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentBlueprintRepository.cs
index d137d7ac76b8..c654e1a6c2cc 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentBlueprintRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentBlueprintRepository.cs
@@ -2,6 +2,7 @@
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
+using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Scoping;
namespace Umbraco.Core.Persistence.Repositories.Implement
@@ -17,8 +18,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
///
internal class DocumentBlueprintRepository : DocumentRepository, IDocumentBlueprintRepository
{
- public DocumentBlueprintRepository(IScopeAccessor scopeAccessor, AppCaches appCaches, ILogger logger, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, ITagRepository tagRepository, ILanguageRepository languageRepository)
- : base(scopeAccessor, appCaches, logger, contentTypeRepository, templateRepository, tagRepository, languageRepository)
+ public DocumentBlueprintRepository(IScopeAccessor scopeAccessor, AppCaches appCaches, ILogger logger, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, ITagRepository tagRepository, ILanguageRepository languageRepository, PropertyEditorCollection propertyEditors)
+ : base(scopeAccessor, appCaches, logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, propertyEditors)
{
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs
index 2649b9993fed..eb392e86cb0b 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs
@@ -12,6 +12,7 @@
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
+using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
@@ -30,8 +31,8 @@ internal class DocumentRepository : ContentRepositoryBase());
return repository;
}
diff --git a/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs
index 4d62ec830173..424ab145bca1 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs
@@ -69,7 +69,7 @@ private DocumentRepository CreateRepository(IScopeAccessor scopeAccessor, out Co
var commonRepository = new ContentTypeCommonRepository(scopeAccessor, templateRepository, appCaches);
var languageRepository = new LanguageRepository(scopeAccessor, appCaches, Logger);
contentTypeRepository = new ContentTypeRepository(scopeAccessor, appCaches, Logger, commonRepository, languageRepository);
- var repository = new DocumentRepository(scopeAccessor, appCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
+ var repository = new DocumentRepository(scopeAccessor, appCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, Factory.GetInstance());
return repository;
}
diff --git a/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs
index 628f8d75a78d..65b5e8365e49 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs
@@ -3,9 +3,10 @@
using System.Linq;
using Moq;
using NUnit.Framework;
-using Umbraco.Core.Configuration.UmbracoSettings;
+using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.Repositories.Implement;
+using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Scoping;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
@@ -25,7 +26,7 @@ private DomainRepository CreateRepository(IScopeProvider provider, out ContentTy
var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches);
languageRepository = new LanguageRepository(accessor, Core.Cache.AppCaches.Disabled, Logger);
contentTypeRepository = new ContentTypeRepository(accessor, Core.Cache.AppCaches.Disabled, Logger, commonRepository, languageRepository);
- documentRepository = new DocumentRepository(accessor, Core.Cache.AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
+ documentRepository = new DocumentRepository(accessor, Core.Cache.AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, Factory.GetInstance());
var domainRepository = new DomainRepository(accessor, Core.Cache.AppCaches.Disabled, Logger);
return domainRepository;
}
diff --git a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs
index e2123df9e3fd..462c44d325ea 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs
@@ -4,7 +4,7 @@
using NUnit.Framework;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration.UmbracoSettings;
-using Umbraco.Core.IO;
+using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Persistence;
@@ -17,6 +17,7 @@
using Umbraco.Core.Scoping;
using Umbraco.Tests.Testing;
using Umbraco.Core.Services;
+using Umbraco.Core.PropertyEditors;
namespace Umbraco.Tests.Persistence.Repositories
{
@@ -41,7 +42,7 @@ private MediaRepository CreateRepository(IScopeProvider provider, out MediaTypeR
var languageRepository = new LanguageRepository(scopeAccessor, appCaches, Logger);
mediaTypeRepository = new MediaTypeRepository(scopeAccessor, appCaches, Logger, commonRepository, languageRepository);
var tagRepository = new TagRepository(scopeAccessor, appCaches, Logger);
- var repository = new MediaRepository(scopeAccessor, appCaches, Logger, mediaTypeRepository, tagRepository, Mock.Of());
+ var repository = new MediaRepository(scopeAccessor, appCaches, Logger, mediaTypeRepository, tagRepository, Mock.Of(), Factory.GetInstance());
return repository;
}
diff --git a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs
index 17b16ad7ab7f..0b23240615cb 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs
@@ -15,6 +15,7 @@
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.Repositories.Implement;
+using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Scoping;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
@@ -35,7 +36,7 @@ private MemberRepository CreateRepository(IScopeProvider provider, out MemberTyp
memberTypeRepository = new MemberTypeRepository(accessor, AppCaches.Disabled, Logger, commonRepository, languageRepository);
memberGroupRepository = new MemberGroupRepository(accessor, AppCaches.Disabled, Logger);
var tagRepo = new TagRepository(accessor, AppCaches.Disabled, Logger);
- var repository = new MemberRepository(accessor, AppCaches.Disabled, Logger, memberTypeRepository, memberGroupRepository, tagRepo, Mock.Of());
+ var repository = new MemberRepository(accessor, AppCaches.Disabled, Logger, memberTypeRepository, memberGroupRepository, tagRepo, Mock.Of(), Factory.GetInstance());
return repository;
}
diff --git a/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs
index 56041c24aa61..3398e7d24d6b 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs
@@ -3,10 +3,11 @@
using System.Linq;
using Moq;
using NUnit.Framework;
-using Umbraco.Core.Configuration.UmbracoSettings;
+using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Repositories.Implement;
+using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Scoping;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
@@ -310,7 +311,7 @@ private DocumentRepository CreateRepository(IScopeProvider provider, out Content
var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches);
var languageRepository = new LanguageRepository(accessor, AppCaches, Logger);
contentTypeRepository = new ContentTypeRepository(accessor, AppCaches, Logger, commonRepository, languageRepository);
- var repository = new DocumentRepository(accessor, AppCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
+ var repository = new DocumentRepository(accessor, AppCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, Factory.GetInstance());
return repository;
}
diff --git a/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs
index e3de2c28928c..9e7593f4ea0d 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs
@@ -2,11 +2,12 @@
using Moq;
using NUnit.Framework;
using Umbraco.Core.Cache;
-using Umbraco.Core.Configuration.UmbracoSettings;
+using Umbraco.Core;
using Umbraco.Core.IO;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.Repositories.Implement;
+using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Scoping;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
@@ -958,7 +959,7 @@ private DocumentRepository CreateContentRepository(IScopeProvider provider, out
var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches.Disabled);
var languageRepository = new LanguageRepository(accessor, AppCaches.Disabled, Logger);
contentTypeRepository = new ContentTypeRepository(accessor, AppCaches.Disabled, Logger, commonRepository, languageRepository);
- var repository = new DocumentRepository(accessor, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
+ var repository = new DocumentRepository(accessor, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, Factory.GetInstance());
return repository;
}
@@ -970,7 +971,7 @@ private MediaRepository CreateMediaRepository(IScopeProvider provider, out Media
var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches.Disabled);
var languageRepository = new LanguageRepository(accessor, AppCaches.Disabled, Logger);
mediaTypeRepository = new MediaTypeRepository(accessor, AppCaches.Disabled, Logger, commonRepository, languageRepository);
- var repository = new MediaRepository(accessor, AppCaches.Disabled, Logger, mediaTypeRepository, tagRepository, Mock.Of());
+ var repository = new MediaRepository(accessor, AppCaches.Disabled, Logger, mediaTypeRepository, tagRepository, Mock.Of(), Factory.GetInstance());
return repository;
}
}
diff --git a/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs
index b0f9a5335b6a..941ba843515e 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs
@@ -12,6 +12,7 @@
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.Repositories.Implement;
+using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Scoping;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
@@ -241,7 +242,7 @@ public void Can_Perform_Delete_When_Assigned_To_Doc()
var commonRepository = new ContentTypeCommonRepository(ScopeProvider, templateRepository, AppCaches);
var languageRepository = new LanguageRepository((IScopeAccessor) ScopeProvider, AppCaches.Disabled, Logger);
var contentTypeRepository = new ContentTypeRepository((IScopeAccessor) ScopeProvider, AppCaches.Disabled, Logger, commonRepository, languageRepository);
- var contentRepo = new DocumentRepository((IScopeAccessor) ScopeProvider, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
+ var contentRepo = new DocumentRepository((IScopeAccessor) ScopeProvider, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, Factory.GetInstance());
var contentType = MockedContentTypes.CreateSimpleContentType("umbTextpage2", "Textpage");
ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType!
diff --git a/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs
index 3e5919d7f30c..c406a5c70479 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs
@@ -14,6 +14,7 @@
using Umbraco.Tests.TestHelpers.Entities;
using Umbraco.Tests.Testing;
using Umbraco.Core.Persistence;
+using Umbraco.Core.PropertyEditors;
namespace Umbraco.Tests.Persistence.Repositories
{
@@ -29,7 +30,7 @@ private MediaRepository CreateMediaRepository(IScopeProvider provider, out IMedi
var languageRepository = new LanguageRepository(accessor, AppCaches, Logger);
mediaTypeRepository = new MediaTypeRepository(accessor, AppCaches, Mock.Of(), commonRepository, languageRepository);
var tagRepository = new TagRepository(accessor, AppCaches, Mock.Of());
- var repository = new MediaRepository(accessor, AppCaches, Mock.Of(), mediaTypeRepository, tagRepository, Mock.Of());
+ var repository = new MediaRepository(accessor, AppCaches, Mock.Of(), mediaTypeRepository, tagRepository, Mock.Of(), Factory.GetInstance());
return repository;
}
@@ -47,7 +48,7 @@ private DocumentRepository CreateContentRepository(IScopeProvider provider, out
var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches);
var languageRepository = new LanguageRepository(accessor, AppCaches, Logger);
contentTypeRepository = new ContentTypeRepository(accessor, AppCaches, Logger, commonRepository, languageRepository);
- var repository = new DocumentRepository(accessor, AppCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
+ var repository = new DocumentRepository(accessor, AppCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, Factory.GetInstance());
return repository;
}
diff --git a/src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs b/src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs
index ef80672bafee..c77bb714940d 100644
--- a/src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs
+++ b/src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs
@@ -14,6 +14,7 @@
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.Repositories.Implement;
+using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Scoping;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
@@ -168,7 +169,7 @@ public void Getting_100_Uncached_Items()
var commonRepository = new ContentTypeCommonRepository((IScopeAccessor)provider, tRepository, AppCaches);
var languageRepository = new LanguageRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger);
var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository, languageRepository);
- var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository);
+ var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository, Factory.GetInstance());
// Act
Stopwatch watch = Stopwatch.StartNew();
@@ -202,7 +203,7 @@ public void Getting_1000_Uncached_Items()
var commonRepository = new ContentTypeCommonRepository((IScopeAccessor)provider, tRepository, AppCaches);
var languageRepository = new LanguageRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger);
var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository, languageRepository);
- var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository);
+ var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository, Factory.GetInstance());
// Act
Stopwatch watch = Stopwatch.StartNew();
@@ -234,7 +235,7 @@ public void Getting_100_Cached_Items()
var commonRepository = new ContentTypeCommonRepository((IScopeAccessor) provider, tRepository, AppCaches);
var languageRepository = new LanguageRepository((IScopeAccessor)provider, AppCaches.Disabled, Logger);
var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository, languageRepository);
- var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository);
+ var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository, Factory.GetInstance());
// Act
var contents = repository.GetMany();
@@ -269,7 +270,7 @@ public void Getting_1000_Cached_Items()
var commonRepository = new ContentTypeCommonRepository((IScopeAccessor)provider, tRepository, AppCaches);
var languageRepository = new LanguageRepository((IScopeAccessor)provider, AppCaches.Disabled, Logger);
var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository, languageRepository);
- var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository);
+ var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository, Factory.GetInstance());
// Act
var contents = repository.GetMany();
diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs
index e26e764cd16f..65c3b9f8a715 100644
--- a/src/Umbraco.Tests/Services/ContentServiceTests.cs
+++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs
@@ -3166,7 +3166,7 @@ private DocumentRepository CreateRepository(IScopeProvider provider, out Content
var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches);
var languageRepository = new LanguageRepository(accessor, AppCaches.Disabled, Logger);
contentTypeRepository = new ContentTypeRepository(accessor, AppCaches.Disabled, Logger, commonRepository, languageRepository);
- var repository = new DocumentRepository(accessor, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
+ var repository = new DocumentRepository(accessor, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, Factory.GetInstance());
return repository;
}
From a78a4ff8075ace6b97d49b4b20c992c5c7647a33 Mon Sep 17 00:00:00 2001
From: Shannon
Date: Mon, 21 Oct 2019 22:56:02 +1100
Subject: [PATCH 03/15] Less statics, new InternalLinkParserTests, better
testing support on UDI, less singletons
---
.../PropertyEditors/IDataValueReference.cs | 2 +-
src/Umbraco.Core/Udi.cs | 2 +-
src/Umbraco.Tests/Umbraco.Tests.csproj | 1 +
.../Web/InternalLinkParserTests.cs | 88 ++++++++++++++++++
.../Web/TemplateUtilitiesTests.cs | 71 +--------------
.../MarkdownEditorValueConverter.cs | 9 +-
.../RteMacroRenderingValueConverter.cs | 6 +-
.../TextStringValueConverter.cs | 8 +-
src/Umbraco.Web/Routing/UrlProvider.cs | 13 +++
src/Umbraco.Web/Runtime/WebInitialComposer.cs | 2 +
.../Templates/InternalLinkParser.cs | 91 +++++++++++++++++++
.../Templates/TemplateUtilities.cs | 73 ++-------------
src/Umbraco.Web/Umbraco.Web.csproj | 1 +
src/Umbraco.Web/UmbracoComponentRenderer.cs | 6 +-
14 files changed, 232 insertions(+), 141 deletions(-)
create mode 100644 src/Umbraco.Tests/Web/InternalLinkParserTests.cs
create mode 100644 src/Umbraco.Web/Templates/InternalLinkParser.cs
diff --git a/src/Umbraco.Core/PropertyEditors/IDataValueReference.cs b/src/Umbraco.Core/PropertyEditors/IDataValueReference.cs
index d7d848f1bfe1..e71642f8a385 100644
--- a/src/Umbraco.Core/PropertyEditors/IDataValueReference.cs
+++ b/src/Umbraco.Core/PropertyEditors/IDataValueReference.cs
@@ -3,7 +3,7 @@
namespace Umbraco.Core.PropertyEditors
{
///
- /// Used to resolve references from values
+ /// Resolve references from values
///
public interface IDataValueReference
{
diff --git a/src/Umbraco.Core/Udi.cs b/src/Umbraco.Core/Udi.cs
index c7297b8c093b..e7d00fffa59a 100644
--- a/src/Umbraco.Core/Udi.cs
+++ b/src/Umbraco.Core/Udi.cs
@@ -233,7 +233,7 @@ private static void EnsureScanForUdiTypes()
// just pick every service connectors - just making sure that not two of them
// would register the same entity type, with different udi types (would not make
// much sense anyways).
- var connectors = Current.TypeLoader.GetTypes();
+ var connectors = Current.HasFactory ? (Current.TypeLoader?.GetTypes() ?? Enumerable.Empty()) : Enumerable.Empty();
var result = new Dictionary();
foreach (var connector in connectors)
{
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index 39826fcc38db..e73caf45171a 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -253,6 +253,7 @@
+
diff --git a/src/Umbraco.Tests/Web/InternalLinkParserTests.cs b/src/Umbraco.Tests/Web/InternalLinkParserTests.cs
new file mode 100644
index 000000000000..815ce408eeef
--- /dev/null
+++ b/src/Umbraco.Tests/Web/InternalLinkParserTests.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Linq;
+using System.Web;
+using Moq;
+using NUnit.Framework;
+using Umbraco.Core.Configuration.UmbracoSettings;
+using Umbraco.Core.Models;
+using Umbraco.Core.Models.PublishedContent;
+using Umbraco.Core.Services;
+using Umbraco.Tests.TestHelpers;
+using Umbraco.Tests.Testing.Objects.Accessors;
+using Umbraco.Web;
+using Umbraco.Web.PublishedCache;
+using Umbraco.Web.Routing;
+using Umbraco.Web.Templates;
+
+namespace Umbraco.Tests.Web
+{
+ [TestFixture]
+ public class InternalLinkParserTests
+ {
+ [TestCase("", "")]
+ [TestCase("hello href=\"{localLink:1234}\" world ", "hello href=\"/my-test-url\" world ")]
+ [TestCase("hello href=\"{localLink:umb://document/9931BDE0-AAC3-4BAB-B838-909A7B47570E}\" world ", "hello href=\"/my-test-url\" world ")]
+ [TestCase("hello href=\"{localLink:umb://document/9931BDE0AAC34BABB838909A7B47570E}\" world ", "hello href=\"/my-test-url\" world ")]
+ [TestCase("hello href=\"{localLink:umb://media/9931BDE0AAC34BABB838909A7B47570E}\" world ", "hello href=\"/media/1001/my-image.jpg\" world ")]
+ //this one has an invalid char so won't match
+ [TestCase("hello href=\"{localLink:umb^://document/9931BDE0-AAC3-4BAB-B838-909A7B47570E}\" world ", "hello href=\"{localLink:umb^://document/9931BDE0-AAC3-4BAB-B838-909A7B47570E}\" world ")]
+ [TestCase("hello href=\"{localLink:umb://document-type/9931BDE0-AAC3-4BAB-B838-909A7B47570E}\" world ", "hello href=\"#\" world ")]
+ public void ParseLocalLinks(string input, string result)
+ {
+ var serviceCtxMock = new TestObjects(null).GetServiceContextMock();
+
+ //setup a mock url provider which we'll use for testing
+ var testUrlProvider = new Mock();
+ testUrlProvider
+ .Setup(x => x.GetUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()))
+ .Returns(UrlInfo.Url("/my-test-url"));
+
+ var globalSettings = SettingsForTests.GenerateMockGlobalSettings();
+
+ var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
+ var publishedContent = new Mock();
+ publishedContent.Setup(x => x.Id).Returns(1234);
+ publishedContent.Setup(x => x.ContentType).Returns(contentType);
+ var contentCache = new Mock();
+ contentCache.Setup(x => x.GetById(It.IsAny())).Returns(publishedContent.Object);
+ contentCache.Setup(x => x.GetById(It.IsAny())).Returns(publishedContent.Object);
+ var mediaType = new PublishedContentType(777, "image", PublishedItemType.Media, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
+ var media = new Mock();
+ media.Setup(x => x.Url).Returns("/media/1001/my-image.jpg");
+ media.Setup(x => x.ContentType).Returns(mediaType);
+ var mediaCache = new Mock();
+ mediaCache.Setup(x => x.GetById(It.IsAny())).Returns(media.Object);
+ mediaCache.Setup(x => x.GetById(It.IsAny())).Returns(media.Object);
+ var snapshot = new Mock();
+ snapshot.Setup(x => x.Content).Returns(contentCache.Object);
+ snapshot.Setup(x => x.Media).Returns(mediaCache.Object);
+ var snapshotService = new Mock();
+ snapshotService.Setup(x => x.CreatePublishedSnapshot(It.IsAny())).Returns(snapshot.Object);
+ var mediaUrlProvider = new Mock();
+ mediaUrlProvider.Setup(x => x.GetMediaUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()))
+ .Returns(UrlInfo.Url("/media/1001/my-image.jpg"));
+
+ var umbracoContextAccessor = new TestUmbracoContextAccessor();
+
+ var umbracoContextFactory = new UmbracoContextFactory(
+ umbracoContextAccessor,
+ snapshotService.Object,
+ new TestVariationContextAccessor(),
+ new TestDefaultCultureAccessor(),
+ Mock.Of(section => section.WebRouting == Mock.Of(routingSection => routingSection.UrlProviderMode == "Auto")),
+ globalSettings,
+ new UrlProviderCollection(new[] { testUrlProvider.Object }),
+ new MediaUrlProviderCollection(new[] { mediaUrlProvider.Object }),
+ Mock.Of());
+
+ using (var reference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of()))
+ {
+ var linkParser = new InternalLinkParser(umbracoContextAccessor);
+
+ var output = linkParser.ParseInternalLinks(input);
+
+ Assert.AreEqual(result, output);
+ }
+ }
+ }
+}
diff --git a/src/Umbraco.Tests/Web/TemplateUtilitiesTests.cs b/src/Umbraco.Tests/Web/TemplateUtilitiesTests.cs
index 3a5405548b70..ef2333043124 100644
--- a/src/Umbraco.Tests/Web/TemplateUtilitiesTests.cs
+++ b/src/Umbraco.Tests/Web/TemplateUtilitiesTests.cs
@@ -1,6 +1,4 @@
using System;
-using System.Linq;
-using System.Web;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
@@ -9,20 +7,16 @@
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
-using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Services;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.Testing.Objects.Accessors;
-using Umbraco.Web;
-using Umbraco.Web.PublishedCache;
-using Umbraco.Web.Routing;
using Umbraco.Web.Security;
-using Umbraco.Web.Templates;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
namespace Umbraco.Tests.Web
{
+
[TestFixture]
public class TemplateUtilitiesTests
{
@@ -59,67 +53,6 @@ public void TearDown()
Current.Reset();
}
- [TestCase("", "")]
- [TestCase("hello href=\"{localLink:1234}\" world ", "hello href=\"/my-test-url\" world ")]
- [TestCase("hello href=\"{localLink:umb://document/9931BDE0-AAC3-4BAB-B838-909A7B47570E}\" world ", "hello href=\"/my-test-url\" world ")]
- [TestCase("hello href=\"{localLink:umb://document/9931BDE0AAC34BABB838909A7B47570E}\" world ", "hello href=\"/my-test-url\" world ")]
- [TestCase("hello href=\"{localLink:umb://media/9931BDE0AAC34BABB838909A7B47570E}\" world ", "hello href=\"/media/1001/my-image.jpg\" world ")]
- //this one has an invalid char so won't match
- [TestCase("hello href=\"{localLink:umb^://document/9931BDE0-AAC3-4BAB-B838-909A7B47570E}\" world ", "hello href=\"{localLink:umb^://document/9931BDE0-AAC3-4BAB-B838-909A7B47570E}\" world ")]
- [TestCase("hello href=\"{localLink:umb://document-type/9931BDE0-AAC3-4BAB-B838-909A7B47570E}\" world ", "hello href=\"#\" world ")]
- public void ParseLocalLinks(string input, string result)
- {
- var serviceCtxMock = new TestObjects(null).GetServiceContextMock();
-
- //setup a mock entity service from the service context to return an integer for a GUID
- var entityService = Mock.Get(serviceCtxMock.EntityService);
- //entityService.Setup(x => x.GetId(It.IsAny(), It.IsAny()))
- // .Returns((Guid id, UmbracoObjectTypes objType) =>
- // {
- // return Attempt.Succeed(1234);
- // });
-
- //setup a mock url provider which we'll use for testing
- var testUrlProvider = new Mock();
- testUrlProvider
- .Setup(x => x.GetUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()))
- .Returns((UmbracoContext umbCtx, IPublishedContent content, UrlMode mode, string culture, Uri url) => UrlInfo.Url("/my-test-url"));
-
- var globalSettings = SettingsForTests.GenerateMockGlobalSettings();
-
- var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
- var publishedContent = Mock.Of();
- Mock.Get(publishedContent).Setup(x => x.Id).Returns(1234);
- Mock.Get(publishedContent).Setup(x => x.ContentType).Returns(contentType);
- var contentCache = Mock.Of();
- Mock.Get(contentCache).Setup(x => x.GetById(It.IsAny())).Returns(publishedContent);
- Mock.Get(contentCache).Setup(x => x.GetById(It.IsAny())).Returns(publishedContent);
- var snapshot = Mock.Of();
- Mock.Get(snapshot).Setup(x => x.Content).Returns(contentCache);
- var snapshotService = Mock.Of();
- Mock.Get(snapshotService).Setup(x => x.CreatePublishedSnapshot(It.IsAny())).Returns(snapshot);
- var media = Mock.Of();
- Mock.Get(media).Setup(x => x.Url).Returns("/media/1001/my-image.jpg");
- var mediaCache = Mock.Of();
- Mock.Get(mediaCache).Setup(x => x.GetById(It.IsAny())).Returns(media);
-
- var umbracoContextFactory = new UmbracoContextFactory(
- Umbraco.Web.Composing.Current.UmbracoContextAccessor,
- snapshotService,
- new TestVariationContextAccessor(),
- new TestDefaultCultureAccessor(),
- Mock.Of(section => section.WebRouting == Mock.Of(routingSection => routingSection.UrlProviderMode == "Auto")),
- globalSettings,
- new UrlProviderCollection(new[] { testUrlProvider.Object }),
- new MediaUrlProviderCollection(Enumerable.Empty()),
- Mock.Of());
-
- using (var reference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of()))
- {
- var output = TemplateUtilities.ParseInternalLinks(input, reference.UmbracoContext.UrlProvider, mediaCache);
-
- Assert.AreEqual(result, output);
- }
- }
+
}
}
diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs
index e11f3e0d3ac7..98413c7b7088 100644
--- a/src/Umbraco.Web/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs
+++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs
@@ -12,6 +12,13 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
[DefaultPropertyValueConverter]
public class MarkdownEditorValueConverter : PropertyValueConverterBase
{
+ private readonly InternalLinkParser _localLinkParser;
+
+ public MarkdownEditorValueConverter(InternalLinkParser localLinkParser)
+ {
+ _localLinkParser = localLinkParser;
+ }
+
public override bool IsConverter(IPublishedPropertyType propertyType)
=> Constants.PropertyEditors.Aliases.MarkdownEditor == propertyType.EditorAlias;
@@ -27,7 +34,7 @@ public override object ConvertSourceToIntermediate(IPublishedElement owner, IPub
var sourceString = source.ToString();
// ensures string is parsed for {localLink} and urls are resolved correctly
- sourceString = TemplateUtilities.ParseInternalLinks(sourceString, preview, Current.UmbracoContext);
+ sourceString = _localLinkParser.ParseInternalLinks(sourceString, preview);
sourceString = TemplateUtilities.ResolveUrlsFromTextString(sourceString);
return sourceString;
diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs
index d5e1f841ea1d..95cf2cfc855e 100644
--- a/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs
+++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs
@@ -24,6 +24,7 @@ public class RteMacroRenderingValueConverter : TinyMceValueConverter
{
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
private readonly IMacroRenderer _macroRenderer;
+ private readonly InternalLinkParser _internalLinkParser;
public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType)
{
@@ -32,10 +33,11 @@ public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType
return PropertyCacheLevel.Snapshot;
}
- public RteMacroRenderingValueConverter(IUmbracoContextAccessor umbracoContextAccessor, IMacroRenderer macroRenderer)
+ public RteMacroRenderingValueConverter(IUmbracoContextAccessor umbracoContextAccessor, IMacroRenderer macroRenderer, InternalLinkParser internalLinkParser)
{
_umbracoContextAccessor = umbracoContextAccessor;
_macroRenderer = macroRenderer;
+ _internalLinkParser = internalLinkParser;
}
// NOT thread-safe over a request because it modifies the
@@ -81,7 +83,7 @@ private string Convert(object source, bool preview)
var sourceString = source.ToString();
// ensures string is parsed for {localLink} and urls and media are resolved correctly
- sourceString = TemplateUtilities.ParseInternalLinks(sourceString, preview, Current.UmbracoContext);
+ sourceString = _internalLinkParser.ParseInternalLinks(sourceString, preview);
sourceString = TemplateUtilities.ResolveUrlsFromTextString(sourceString);
sourceString = TemplateUtilities.ResolveMediaFromTextString(sourceString);
diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/TextStringValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/TextStringValueConverter.cs
index b8ad1477b4e8..ee49536d9d72 100644
--- a/src/Umbraco.Web/PropertyEditors/ValueConverters/TextStringValueConverter.cs
+++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/TextStringValueConverter.cs
@@ -11,11 +11,17 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
[DefaultPropertyValueConverter]
public class TextStringValueConverter : PropertyValueConverterBase
{
+ public TextStringValueConverter(InternalLinkParser internalLinkParser)
+ {
+ _internalLinkParser = internalLinkParser;
+ }
+
private static readonly string[] PropertyTypeAliases =
{
Constants.PropertyEditors.Aliases.TextBox,
Constants.PropertyEditors.Aliases.TextArea
};
+ private readonly InternalLinkParser _internalLinkParser;
public override bool IsConverter(IPublishedPropertyType propertyType)
=> PropertyTypeAliases.Contains(propertyType.EditorAlias);
@@ -32,7 +38,7 @@ public override object ConvertSourceToIntermediate(IPublishedElement owner, IPub
var sourceString = source.ToString();
// ensures string is parsed for {localLink} and urls are resolved correctly
- sourceString = TemplateUtilities.ParseInternalLinks(sourceString, preview, Current.UmbracoContext);
+ sourceString = _internalLinkParser.ParseInternalLinks(sourceString, preview);
sourceString = TemplateUtilities.ResolveUrlsFromTextString(sourceString);
return sourceString;
diff --git a/src/Umbraco.Web/Routing/UrlProvider.cs b/src/Umbraco.Web/Routing/UrlProvider.cs
index 59e39fa80aba..d42639b781c5 100644
--- a/src/Umbraco.Web/Routing/UrlProvider.cs
+++ b/src/Umbraco.Web/Routing/UrlProvider.cs
@@ -75,6 +75,7 @@ public UrlProvider(UmbracoContext umbracoContext, IEnumerable urlP
private UrlMode GetMode(bool absolute) => absolute ? UrlMode.Absolute : Mode;
private IPublishedContent GetDocument(int id) => _umbracoContext.Content.GetById(id);
private IPublishedContent GetDocument(Guid id) => _umbracoContext.Content.GetById(id);
+ private IPublishedContent GetMedia(Guid id) => _umbracoContext.Media.GetById(id);
///
/// Gets the url of a published content.
@@ -184,6 +185,18 @@ public IEnumerable GetOtherUrls(int id, Uri current)
#region GetMediaUrl
+ ///
+ /// Gets the url of a media item.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public string GetMediaUrl(Guid id, UrlMode mode = UrlMode.Default, string culture = null, string propertyAlias = Constants.Conventions.Media.File, Uri current = null)
+ => GetMediaUrl(GetMedia(id), mode, culture, propertyAlias, current);
+
///
/// Gets the url of a media item.
///
diff --git a/src/Umbraco.Web/Runtime/WebInitialComposer.cs b/src/Umbraco.Web/Runtime/WebInitialComposer.cs
index 87c0f46fba43..82137bbd9d68 100644
--- a/src/Umbraco.Web/Runtime/WebInitialComposer.cs
+++ b/src/Umbraco.Web/Runtime/WebInitialComposer.cs
@@ -107,6 +107,8 @@ public override void Compose(Composition composition)
composition.RegisterUnique();
composition.RegisterUnique();
+ composition.RegisterUnique();
+
// register the umbraco helper - this is Transient! very important!
// also, if not level.Run, we cannot really use the helper (during upgrade...)
// so inject a "void" helper (not exactly pretty but...)
diff --git a/src/Umbraco.Web/Templates/InternalLinkParser.cs b/src/Umbraco.Web/Templates/InternalLinkParser.cs
new file mode 100644
index 000000000000..0d8a480a9048
--- /dev/null
+++ b/src/Umbraco.Web/Templates/InternalLinkParser.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Text.RegularExpressions;
+using Umbraco.Core;
+using Umbraco.Core.Logging;
+using Umbraco.Web.PublishedCache;
+using Umbraco.Web.Routing;
+
+namespace Umbraco.Web.Templates
+{
+ ///
+ /// Utility class used to parse internal links
+ ///
+ public sealed class InternalLinkParser
+ {
+
+ private static readonly Regex LocalLinkPattern = new Regex(@"href=""[/]?(?:\{|\%7B)localLink:([a-zA-Z0-9-://]+)(?:\}|\%7D)",
+ RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
+
+ private readonly IUmbracoContextAccessor _umbracoContextAccessor;
+
+ public InternalLinkParser(IUmbracoContextAccessor umbracoContextAccessor)
+ {
+ _umbracoContextAccessor = umbracoContextAccessor;
+ }
+
+ public string ParseInternalLinks(string text, bool preview)
+ {
+ if (_umbracoContextAccessor.UmbracoContext == null)
+ throw new InvalidOperationException("Could not parse internal links, there is no current UmbracoContext");
+
+ if (!preview)
+ return ParseInternalLinks(text);
+
+ using (_umbracoContextAccessor.UmbracoContext.ForcedPreview(preview)) // force for url provider
+ {
+ return ParseInternalLinks(text);
+ }
+ }
+
+ ///
+ /// Parses the string looking for the {localLink} syntax and updates them to their correct links.
+ ///
+ ///
+ ///
+ ///
+ public string ParseInternalLinks(string text)
+ {
+ if (_umbracoContextAccessor.UmbracoContext == null)
+ throw new InvalidOperationException("Could not parse internal links, there is no current UmbracoContext");
+
+ var urlProvider = _umbracoContextAccessor.UmbracoContext.UrlProvider;
+
+ // Parse internal links
+ var tags = LocalLinkPattern.Matches(text);
+ foreach (Match tag in tags)
+ {
+ if (tag.Groups.Count > 0)
+ {
+ var id = tag.Groups[1].Value; //.Remove(tag.Groups[1].Value.Length - 1, 1);
+
+ //The id could be an int or a UDI
+ if (Udi.TryParse(id, out var udi))
+ {
+ var guidUdi = udi as GuidUdi;
+ if (guidUdi != null)
+ {
+ var newLink = "#";
+ if (guidUdi.EntityType == Constants.UdiEntityType.Document)
+ newLink = urlProvider.GetUrl(guidUdi.Guid);
+ else if (guidUdi.EntityType == Constants.UdiEntityType.Media)
+ newLink = urlProvider.GetMediaUrl(guidUdi.Guid);
+
+ if (newLink == null)
+ newLink = "#";
+
+ text = text.Replace(tag.Value, "href=\"" + newLink);
+ }
+ }
+
+ if (int.TryParse(id, out var intId))
+ {
+ var newLink = urlProvider.GetUrl(intId);
+ text = text.Replace(tag.Value, "href=\"" + newLink);
+ }
+ }
+ }
+
+ return text;
+ }
+ }
+}
diff --git a/src/Umbraco.Web/Templates/TemplateUtilities.cs b/src/Umbraco.Web/Templates/TemplateUtilities.cs
index 58d3ed341e8d..1092be73e24f 100644
--- a/src/Umbraco.Web/Templates/TemplateUtilities.cs
+++ b/src/Umbraco.Web/Templates/TemplateUtilities.cs
@@ -15,8 +15,6 @@
namespace Umbraco.Web.Templates
{
- //NOTE: I realize there is only one class in this namespace but I'm pretty positive that there will be more classes in
- //this namespace once we start migrating and cleaning up more code.
///
/// Utility class used for templates
@@ -24,7 +22,14 @@ namespace Umbraco.Web.Templates
public static class TemplateUtilities
{
const string TemporaryImageDataAttribute = "data-tmpimg";
+
+ private static readonly Regex ResolveUrlPattern = new Regex("(=[\"\']?)(\\W?\\~(?:.(?![\"\']?\\s+(?:\\S+)=|[>\"\']))+.)[\"\']?",
+ RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
+
+ private static readonly Regex ResolveImgPattern = new Regex(@"(]*src="")([^""\?]*)([^""]*""[^>]*data-udi="")([^""]*)(""[^>]*>)",
+ RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
+ [Obsolete("Inject and use an instance of InternalLinkParser instead")]
internal static string ParseInternalLinks(string text, bool preview, UmbracoContext umbracoContext)
{
using (umbracoContext.ForcedPreview(preview)) // force for url provider
@@ -35,69 +40,9 @@ internal static string ParseInternalLinks(string text, bool preview, UmbracoCont
return text;
}
- ///
- /// Parses the string looking for the {localLink} syntax and updates them to their correct links.
- ///
- ///
- ///
- ///
+ [Obsolete("Inject and use an instance of InternalLinkParser instead")]
public static string ParseInternalLinks(string text, UrlProvider urlProvider) =>
- ParseInternalLinks(text, urlProvider, Current.UmbracoContext.MediaCache);
-
- // TODO: Replace mediaCache with media url provider
- internal static string ParseInternalLinks(string text, UrlProvider urlProvider, IPublishedMediaCache mediaCache)
- {
- if (urlProvider == null) throw new ArgumentNullException(nameof(urlProvider));
- if (mediaCache == null) throw new ArgumentNullException(nameof(mediaCache));
-
- // Parse internal links
- var tags = LocalLinkPattern.Matches(text);
- foreach (Match tag in tags)
- {
- if (tag.Groups.Count > 0)
- {
- var id = tag.Groups[1].Value; //.Remove(tag.Groups[1].Value.Length - 1, 1);
-
- //The id could be an int or a UDI
- if (Udi.TryParse(id, out var udi))
- {
- var guidUdi = udi as GuidUdi;
- if (guidUdi != null)
- {
- var newLink = "#";
- if (guidUdi.EntityType == Constants.UdiEntityType.Document)
- newLink = urlProvider.GetUrl(guidUdi.Guid);
- else if (guidUdi.EntityType == Constants.UdiEntityType.Media)
- newLink = mediaCache.GetById(guidUdi.Guid)?.Url;
-
- if (newLink == null)
- newLink = "#";
-
- text = text.Replace(tag.Value, "href=\"" + newLink);
- }
- }
-
- if (int.TryParse(id, out var intId))
- {
- var newLink = urlProvider.GetUrl(intId);
- text = text.Replace(tag.Value, "href=\"" + newLink);
- }
- }
- }
-
- return text;
- }
-
-
- // static compiled regex for faster performance
- private static readonly Regex LocalLinkPattern = new Regex(@"href=""[/]?(?:\{|\%7B)localLink:([a-zA-Z0-9-://]+)(?:\}|\%7D)",
- RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
-
- private static readonly Regex ResolveUrlPattern = new Regex("(=[\"\']?)(\\W?\\~(?:.(?![\"\']?\\s+(?:\\S+)=|[>\"\']))+.)[\"\']?",
- RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
-
- private static readonly Regex ResolveImgPattern = new Regex(@"(]*src="")([^""\?]*)([^""]*""[^>]*data-udi="")([^""]*)(""[^>]*>)",
- RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
+ Current.Factory.GetInstance().ParseInternalLinks(text);
///
/// The RegEx matches any HTML attribute values that start with a tilde (~), those that match are passed to ResolveUrl to replace the tilde with the application path.
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index cf149968889a..616ed908e104 100755
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -247,6 +247,7 @@
+
diff --git a/src/Umbraco.Web/UmbracoComponentRenderer.cs b/src/Umbraco.Web/UmbracoComponentRenderer.cs
index f6c3d30da359..805b9267f92e 100644
--- a/src/Umbraco.Web/UmbracoComponentRenderer.cs
+++ b/src/Umbraco.Web/UmbracoComponentRenderer.cs
@@ -27,12 +27,14 @@ internal class UmbracoComponentRenderer : IUmbracoComponentRenderer
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
private readonly IMacroRenderer _macroRenderer;
private readonly ITemplateRenderer _templateRenderer;
+ private readonly InternalLinkParser _internalLinkParser;
- public UmbracoComponentRenderer(IUmbracoContextAccessor umbracoContextAccessor, IMacroRenderer macroRenderer, ITemplateRenderer templateRenderer)
+ public UmbracoComponentRenderer(IUmbracoContextAccessor umbracoContextAccessor, IMacroRenderer macroRenderer, ITemplateRenderer templateRenderer, InternalLinkParser internalLinkParser)
{
_umbracoContextAccessor = umbracoContextAccessor;
_macroRenderer = macroRenderer;
_templateRenderer = templateRenderer ?? throw new ArgumentNullException(nameof(templateRenderer));
+ _internalLinkParser = internalLinkParser;
}
///
@@ -157,7 +159,7 @@ private IHtmlString RenderMacro(string alias, IDictionary parame
_umbracoContextAccessor.UmbracoContext.HttpContext.Response.ContentType = contentType;
//Now, we need to ensure that local links are parsed
- html = TemplateUtilities.ParseInternalLinks(output.ToString(), _umbracoContextAccessor.UmbracoContext.UrlProvider);
+ html = _internalLinkParser.ParseInternalLinks(output.ToString());
}
}
From 8ccebd8006b8eba225fb496d67c3e1b4364e5675 Mon Sep 17 00:00:00 2001
From: Shannon
Date: Mon, 21 Oct 2019 23:04:25 +1100
Subject: [PATCH 04/15] Revert "Removes singleton accessors from repositories"
- this causes a circular ref?!
---
.../Repositories/Implement/ContentRepositoryBase.cs | 5 ++---
.../Implement/DocumentBlueprintRepository.cs | 5 ++---
.../Repositories/Implement/DocumentRepository.cs | 5 ++---
.../Repositories/Implement/MediaRepository.cs | 5 ++---
.../Repositories/Implement/MemberRepository.cs | 5 ++---
.../Repositories/ContentTypeRepositoryTest.cs | 3 +--
.../Persistence/Repositories/DocumentRepositoryTest.cs | 2 +-
.../Persistence/Repositories/DomainRepositoryTest.cs | 5 ++---
.../Persistence/Repositories/MediaRepositoryTest.cs | 5 ++---
.../Persistence/Repositories/MemberRepositoryTest.cs | 3 +--
.../Repositories/PublicAccessRepositoryTest.cs | 5 ++---
.../Persistence/Repositories/TagRepositoryTest.cs | 7 +++----
.../Persistence/Repositories/TemplateRepositoryTest.cs | 3 +--
.../Persistence/Repositories/UserRepositoryTest.cs | 5 ++---
.../Services/ContentServicePerformanceTest.cs | 9 ++++-----
src/Umbraco.Tests/Services/ContentServiceTests.cs | 2 +-
16 files changed, 30 insertions(+), 44 deletions(-)
diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs
index a6ae2fc7e096..7ab73f3f2d51 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs
@@ -33,18 +33,17 @@ internal abstract class ContentRepositoryBase : NPoco
where TEntity : class, IUmbracoEntity
where TRepository : class, IRepository
{
- protected ContentRepositoryBase(IScopeAccessor scopeAccessor, AppCaches cache, ILanguageRepository languageRepository, ILogger logger, PropertyEditorCollection propertyEditors)
+ protected ContentRepositoryBase(IScopeAccessor scopeAccessor, AppCaches cache, ILanguageRepository languageRepository, ILogger logger)
: base(scopeAccessor, cache, logger)
{
LanguageRepository = languageRepository;
- PropertyEditors = propertyEditors;
}
protected abstract TRepository This { get; }
protected ILanguageRepository LanguageRepository { get; }
- protected PropertyEditorCollection PropertyEditors { get; }
+ protected PropertyEditorCollection PropertyEditors => Current.PropertyEditors; // TODO: inject
#region Versions
diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentBlueprintRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentBlueprintRepository.cs
index c654e1a6c2cc..d137d7ac76b8 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentBlueprintRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentBlueprintRepository.cs
@@ -2,7 +2,6 @@
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
-using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Scoping;
namespace Umbraco.Core.Persistence.Repositories.Implement
@@ -18,8 +17,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
///
internal class DocumentBlueprintRepository : DocumentRepository, IDocumentBlueprintRepository
{
- public DocumentBlueprintRepository(IScopeAccessor scopeAccessor, AppCaches appCaches, ILogger logger, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, ITagRepository tagRepository, ILanguageRepository languageRepository, PropertyEditorCollection propertyEditors)
- : base(scopeAccessor, appCaches, logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, propertyEditors)
+ public DocumentBlueprintRepository(IScopeAccessor scopeAccessor, AppCaches appCaches, ILogger logger, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, ITagRepository tagRepository, ILanguageRepository languageRepository)
+ : base(scopeAccessor, appCaches, logger, contentTypeRepository, templateRepository, tagRepository, languageRepository)
{
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs
index eb392e86cb0b..2649b9993fed 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs
@@ -12,7 +12,6 @@
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.SqlSyntax;
-using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
@@ -31,8 +30,8 @@ internal class DocumentRepository : ContentRepositoryBase());
+ var repository = new DocumentRepository(scopeAccessor, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
return repository;
}
diff --git a/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs
index 424ab145bca1..4d62ec830173 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs
@@ -69,7 +69,7 @@ private DocumentRepository CreateRepository(IScopeAccessor scopeAccessor, out Co
var commonRepository = new ContentTypeCommonRepository(scopeAccessor, templateRepository, appCaches);
var languageRepository = new LanguageRepository(scopeAccessor, appCaches, Logger);
contentTypeRepository = new ContentTypeRepository(scopeAccessor, appCaches, Logger, commonRepository, languageRepository);
- var repository = new DocumentRepository(scopeAccessor, appCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, Factory.GetInstance());
+ var repository = new DocumentRepository(scopeAccessor, appCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
return repository;
}
diff --git a/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs
index 65b5e8365e49..628f8d75a78d 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs
@@ -3,10 +3,9 @@
using System.Linq;
using Moq;
using NUnit.Framework;
-using Umbraco.Core;
+using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.Repositories.Implement;
-using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Scoping;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
@@ -26,7 +25,7 @@ private DomainRepository CreateRepository(IScopeProvider provider, out ContentTy
var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches);
languageRepository = new LanguageRepository(accessor, Core.Cache.AppCaches.Disabled, Logger);
contentTypeRepository = new ContentTypeRepository(accessor, Core.Cache.AppCaches.Disabled, Logger, commonRepository, languageRepository);
- documentRepository = new DocumentRepository(accessor, Core.Cache.AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, Factory.GetInstance());
+ documentRepository = new DocumentRepository(accessor, Core.Cache.AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
var domainRepository = new DomainRepository(accessor, Core.Cache.AppCaches.Disabled, Logger);
return domainRepository;
}
diff --git a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs
index 462c44d325ea..e2123df9e3fd 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs
@@ -4,7 +4,7 @@
using NUnit.Framework;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration.UmbracoSettings;
-using Umbraco.Core;
+using Umbraco.Core.IO;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Persistence;
@@ -17,7 +17,6 @@
using Umbraco.Core.Scoping;
using Umbraco.Tests.Testing;
using Umbraco.Core.Services;
-using Umbraco.Core.PropertyEditors;
namespace Umbraco.Tests.Persistence.Repositories
{
@@ -42,7 +41,7 @@ private MediaRepository CreateRepository(IScopeProvider provider, out MediaTypeR
var languageRepository = new LanguageRepository(scopeAccessor, appCaches, Logger);
mediaTypeRepository = new MediaTypeRepository(scopeAccessor, appCaches, Logger, commonRepository, languageRepository);
var tagRepository = new TagRepository(scopeAccessor, appCaches, Logger);
- var repository = new MediaRepository(scopeAccessor, appCaches, Logger, mediaTypeRepository, tagRepository, Mock.Of(), Factory.GetInstance());
+ var repository = new MediaRepository(scopeAccessor, appCaches, Logger, mediaTypeRepository, tagRepository, Mock.Of());
return repository;
}
diff --git a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs
index 0b23240615cb..17b16ad7ab7f 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs
@@ -15,7 +15,6 @@
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.Repositories.Implement;
-using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Scoping;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
@@ -36,7 +35,7 @@ private MemberRepository CreateRepository(IScopeProvider provider, out MemberTyp
memberTypeRepository = new MemberTypeRepository(accessor, AppCaches.Disabled, Logger, commonRepository, languageRepository);
memberGroupRepository = new MemberGroupRepository(accessor, AppCaches.Disabled, Logger);
var tagRepo = new TagRepository(accessor, AppCaches.Disabled, Logger);
- var repository = new MemberRepository(accessor, AppCaches.Disabled, Logger, memberTypeRepository, memberGroupRepository, tagRepo, Mock.Of(), Factory.GetInstance());
+ var repository = new MemberRepository(accessor, AppCaches.Disabled, Logger, memberTypeRepository, memberGroupRepository, tagRepo, Mock.Of());
return repository;
}
diff --git a/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs
index 3398e7d24d6b..56041c24aa61 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs
@@ -3,11 +3,10 @@
using System.Linq;
using Moq;
using NUnit.Framework;
-using Umbraco.Core;
+using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Repositories.Implement;
-using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Scoping;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
@@ -311,7 +310,7 @@ private DocumentRepository CreateRepository(IScopeProvider provider, out Content
var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches);
var languageRepository = new LanguageRepository(accessor, AppCaches, Logger);
contentTypeRepository = new ContentTypeRepository(accessor, AppCaches, Logger, commonRepository, languageRepository);
- var repository = new DocumentRepository(accessor, AppCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, Factory.GetInstance());
+ var repository = new DocumentRepository(accessor, AppCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
return repository;
}
diff --git a/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs
index 9e7593f4ea0d..e3de2c28928c 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs
@@ -2,12 +2,11 @@
using Moq;
using NUnit.Framework;
using Umbraco.Core.Cache;
-using Umbraco.Core;
+using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.Repositories.Implement;
-using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Scoping;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
@@ -959,7 +958,7 @@ private DocumentRepository CreateContentRepository(IScopeProvider provider, out
var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches.Disabled);
var languageRepository = new LanguageRepository(accessor, AppCaches.Disabled, Logger);
contentTypeRepository = new ContentTypeRepository(accessor, AppCaches.Disabled, Logger, commonRepository, languageRepository);
- var repository = new DocumentRepository(accessor, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, Factory.GetInstance());
+ var repository = new DocumentRepository(accessor, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
return repository;
}
@@ -971,7 +970,7 @@ private MediaRepository CreateMediaRepository(IScopeProvider provider, out Media
var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches.Disabled);
var languageRepository = new LanguageRepository(accessor, AppCaches.Disabled, Logger);
mediaTypeRepository = new MediaTypeRepository(accessor, AppCaches.Disabled, Logger, commonRepository, languageRepository);
- var repository = new MediaRepository(accessor, AppCaches.Disabled, Logger, mediaTypeRepository, tagRepository, Mock.Of(), Factory.GetInstance());
+ var repository = new MediaRepository(accessor, AppCaches.Disabled, Logger, mediaTypeRepository, tagRepository, Mock.Of());
return repository;
}
}
diff --git a/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs
index 941ba843515e..b0f9a5335b6a 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs
@@ -12,7 +12,6 @@
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.Repositories.Implement;
-using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Scoping;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
@@ -242,7 +241,7 @@ public void Can_Perform_Delete_When_Assigned_To_Doc()
var commonRepository = new ContentTypeCommonRepository(ScopeProvider, templateRepository, AppCaches);
var languageRepository = new LanguageRepository((IScopeAccessor) ScopeProvider, AppCaches.Disabled, Logger);
var contentTypeRepository = new ContentTypeRepository((IScopeAccessor) ScopeProvider, AppCaches.Disabled, Logger, commonRepository, languageRepository);
- var contentRepo = new DocumentRepository((IScopeAccessor) ScopeProvider, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, Factory.GetInstance());
+ var contentRepo = new DocumentRepository((IScopeAccessor) ScopeProvider, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
var contentType = MockedContentTypes.CreateSimpleContentType("umbTextpage2", "Textpage");
ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType!
diff --git a/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs
index c406a5c70479..3e5919d7f30c 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs
@@ -14,7 +14,6 @@
using Umbraco.Tests.TestHelpers.Entities;
using Umbraco.Tests.Testing;
using Umbraco.Core.Persistence;
-using Umbraco.Core.PropertyEditors;
namespace Umbraco.Tests.Persistence.Repositories
{
@@ -30,7 +29,7 @@ private MediaRepository CreateMediaRepository(IScopeProvider provider, out IMedi
var languageRepository = new LanguageRepository(accessor, AppCaches, Logger);
mediaTypeRepository = new MediaTypeRepository(accessor, AppCaches, Mock.Of(), commonRepository, languageRepository);
var tagRepository = new TagRepository(accessor, AppCaches, Mock.Of());
- var repository = new MediaRepository(accessor, AppCaches, Mock.Of(), mediaTypeRepository, tagRepository, Mock.Of(), Factory.GetInstance());
+ var repository = new MediaRepository(accessor, AppCaches, Mock.Of(), mediaTypeRepository, tagRepository, Mock.Of());
return repository;
}
@@ -48,7 +47,7 @@ private DocumentRepository CreateContentRepository(IScopeProvider provider, out
var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches);
var languageRepository = new LanguageRepository(accessor, AppCaches, Logger);
contentTypeRepository = new ContentTypeRepository(accessor, AppCaches, Logger, commonRepository, languageRepository);
- var repository = new DocumentRepository(accessor, AppCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, Factory.GetInstance());
+ var repository = new DocumentRepository(accessor, AppCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
return repository;
}
diff --git a/src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs b/src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs
index c77bb714940d..ef80672bafee 100644
--- a/src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs
+++ b/src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs
@@ -14,7 +14,6 @@
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.Repositories.Implement;
-using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Scoping;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
@@ -169,7 +168,7 @@ public void Getting_100_Uncached_Items()
var commonRepository = new ContentTypeCommonRepository((IScopeAccessor)provider, tRepository, AppCaches);
var languageRepository = new LanguageRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger);
var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository, languageRepository);
- var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository, Factory.GetInstance());
+ var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository);
// Act
Stopwatch watch = Stopwatch.StartNew();
@@ -203,7 +202,7 @@ public void Getting_1000_Uncached_Items()
var commonRepository = new ContentTypeCommonRepository((IScopeAccessor)provider, tRepository, AppCaches);
var languageRepository = new LanguageRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger);
var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository, languageRepository);
- var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository, Factory.GetInstance());
+ var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository);
// Act
Stopwatch watch = Stopwatch.StartNew();
@@ -235,7 +234,7 @@ public void Getting_100_Cached_Items()
var commonRepository = new ContentTypeCommonRepository((IScopeAccessor) provider, tRepository, AppCaches);
var languageRepository = new LanguageRepository((IScopeAccessor)provider, AppCaches.Disabled, Logger);
var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository, languageRepository);
- var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository, Factory.GetInstance());
+ var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository);
// Act
var contents = repository.GetMany();
@@ -270,7 +269,7 @@ public void Getting_1000_Cached_Items()
var commonRepository = new ContentTypeCommonRepository((IScopeAccessor)provider, tRepository, AppCaches);
var languageRepository = new LanguageRepository((IScopeAccessor)provider, AppCaches.Disabled, Logger);
var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository, languageRepository);
- var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository, Factory.GetInstance());
+ var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository);
// Act
var contents = repository.GetMany();
diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs
index 65c3b9f8a715..e26e764cd16f 100644
--- a/src/Umbraco.Tests/Services/ContentServiceTests.cs
+++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs
@@ -3166,7 +3166,7 @@ private DocumentRepository CreateRepository(IScopeProvider provider, out Content
var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches);
var languageRepository = new LanguageRepository(accessor, AppCaches.Disabled, Logger);
contentTypeRepository = new ContentTypeRepository(accessor, AppCaches.Disabled, Logger, commonRepository, languageRepository);
- var repository = new DocumentRepository(accessor, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, Factory.GetInstance());
+ var repository = new DocumentRepository(accessor, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
return repository;
}
From 4f9e0fcb92e55757b7a0591fa7fa59e4ff257899 Mon Sep 17 00:00:00 2001
From: Shannon
Date: Mon, 21 Oct 2019 23:53:14 +1100
Subject: [PATCH 05/15] No more using TemplateUtilities
---
.../Implement/ContentRepositoryBase.cs | 3 +-
.../PublishedContentTestBase.cs | 5 +-
.../PublishedContent/PublishedContentTests.cs | 4 +-
.../Web/InternalLinkParserTests.cs | 2 +-
.../PropertyEditors/GridPropertyEditor.cs | 16 +-
.../PropertyEditors/RichTextPropertyEditor.cs | 41 ++--
.../MarkdownEditorValueConverter.cs | 8 +-
.../RteMacroRenderingValueConverter.cs | 13 +-
.../TextStringValueConverter.cs | 8 +-
src/Umbraco.Web/Runtime/WebInitialComposer.cs | 2 +
.../Templates/InternalLinkParser.cs | 14 +-
src/Umbraco.Web/Templates/MediaParser.cs | 186 +++++++++++++++
.../Templates/TemplateUtilities.cs | 213 ++----------------
src/Umbraco.Web/Templates/UrlParser.cs | 61 +++++
src/Umbraco.Web/Umbraco.Web.csproj | 2 +
src/Umbraco.Web/UmbracoComponentRenderer.cs | 2 +-
16 files changed, 337 insertions(+), 243 deletions(-)
create mode 100644 src/Umbraco.Web/Templates/MediaParser.cs
create mode 100644 src/Umbraco.Web/Templates/UrlParser.cs
diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs
index 7ab73f3f2d51..7ab9f10e1cdf 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs
@@ -24,6 +24,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
internal sealed class ContentRepositoryBase
{
///
+ ///
/// This is used for unit tests ONLY
///
public static bool ThrowOnWarning = false;
@@ -43,7 +44,7 @@ protected ContentRepositoryBase(IScopeAccessor scopeAccessor, AppCaches cache, I
protected ILanguageRepository LanguageRepository { get; }
- protected PropertyEditorCollection PropertyEditors => Current.PropertyEditors; // TODO: inject
+ protected PropertyEditorCollection PropertyEditors => Current.PropertyEditors; // TODO: inject ... this causes circular refs, not sure which refs they are though
#region Versions
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs
index f1e2bf20d6df..1fa3384d08e4 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs
@@ -11,6 +11,7 @@
using Umbraco.Web.PropertyEditors;
using Umbraco.Core.Services;
using Umbraco.Web;
+using Umbraco.Web.Templates;
namespace Umbraco.Tests.PublishedContent
{
@@ -38,9 +39,11 @@ protected override void Initialize()
base.Initialize();
var converters = Factory.GetInstance();
+ var umbracoCtxAccessor = Mock.Of();
+ var logger = Mock.Of();
var dataTypeService = new TestObjects.TestDataTypeService(
- new DataType(new RichTextPropertyEditor(Mock.Of(), Mock.Of(), Mock.Of(), Mock.Of())) { Id = 1 });
+ new DataType(new RichTextPropertyEditor(logger, umbracoCtxAccessor, new MediaParser(umbracoCtxAccessor, logger, Mock.Of(), Mock.Of()))) { Id = 1 });
var publishedContentTypeFactory = new PublishedContentTypeFactory(Mock.Of(), converters, dataTypeService);
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
index 6ef632bf90dc..d2f7283ee549 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
@@ -21,6 +21,7 @@
using Umbraco.Tests.Testing;
using Umbraco.Web.Models.PublishedContent;
using Umbraco.Web.PropertyEditors;
+using Umbraco.Web.Templates;
namespace Umbraco.Tests.PublishedContent
{
@@ -45,11 +46,12 @@ protected override void Compose()
var mediaService = Mock.Of();
var contentTypeBaseServiceProvider = Mock.Of();
var umbracoContextAccessor = Mock.Of();
+ var mediaParser = new MediaParser(umbracoContextAccessor, logger, mediaService, contentTypeBaseServiceProvider);
var dataTypeService = new TestObjects.TestDataTypeService(
new DataType(new VoidEditor(logger)) { Id = 1 },
new DataType(new TrueFalsePropertyEditor(logger)) { Id = 1001 },
- new DataType(new RichTextPropertyEditor(logger, mediaService, contentTypeBaseServiceProvider, umbracoContextAccessor)) { Id = 1002 },
+ new DataType(new RichTextPropertyEditor(logger, umbracoContextAccessor, mediaParser)) { Id = 1002 },
new DataType(new IntegerPropertyEditor(logger)) { Id = 1003 },
new DataType(new TextboxPropertyEditor(logger)) { Id = 1004 },
new DataType(new MediaPickerPropertyEditor(logger)) { Id = 1005 });
diff --git a/src/Umbraco.Tests/Web/InternalLinkParserTests.cs b/src/Umbraco.Tests/Web/InternalLinkParserTests.cs
index 815ce408eeef..6cdff240b8a4 100644
--- a/src/Umbraco.Tests/Web/InternalLinkParserTests.cs
+++ b/src/Umbraco.Tests/Web/InternalLinkParserTests.cs
@@ -79,7 +79,7 @@ public void ParseLocalLinks(string input, string result)
{
var linkParser = new InternalLinkParser(umbracoContextAccessor);
- var output = linkParser.ParseInternalLinks(input);
+ var output = linkParser.EnsureInternalLinks(input);
Assert.AreEqual(result, output);
}
diff --git a/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs
index f782f0928921..bec28e33fdfb 100644
--- a/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs
@@ -28,14 +28,16 @@ public class GridPropertyEditor : DataEditor
private IMediaService _mediaService;
private IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider;
private IUmbracoContextAccessor _umbracoContextAccessor;
+ private readonly MediaParser _mediaParser;
private ILogger _logger;
- public GridPropertyEditor(ILogger logger, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor)
+ public GridPropertyEditor(ILogger logger, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor, MediaParser mediaParser)
: base(logger)
{
_mediaService = mediaService;
_contentTypeBaseServiceProvider = contentTypeBaseServiceProvider;
_umbracoContextAccessor = umbracoContextAccessor;
+ _mediaParser = mediaParser;
_logger = logger;
}
@@ -45,7 +47,7 @@ public GridPropertyEditor(ILogger logger, IMediaService mediaService, IContentTy
/// Overridden to ensure that the value is validated
///
///
- protected override IDataValueEditor CreateValueEditor() => new GridPropertyValueEditor(Attribute, _mediaService, _contentTypeBaseServiceProvider, _umbracoContextAccessor, _logger);
+ protected override IDataValueEditor CreateValueEditor() => new GridPropertyValueEditor(Attribute, _mediaService, _contentTypeBaseServiceProvider, _umbracoContextAccessor, _logger, _mediaParser);
protected override IConfigurationEditor CreateConfigurationEditor() => new GridConfigurationEditor();
@@ -55,14 +57,16 @@ internal class GridPropertyValueEditor : DataValueEditor
private IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider;
private IUmbracoContextAccessor _umbracoContextAccessor;
private ILogger _logger;
+ private readonly MediaParser _mediaParser;
- public GridPropertyValueEditor(DataEditorAttribute attribute, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor, ILogger logger)
+ public GridPropertyValueEditor(DataEditorAttribute attribute, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor, ILogger logger, MediaParser _mediaParser)
: base(attribute)
{
_mediaService = mediaService;
_contentTypeBaseServiceProvider = contentTypeBaseServiceProvider;
_umbracoContextAccessor = umbracoContextAccessor;
_logger = logger;
+ this._mediaParser = _mediaParser;
}
///
@@ -97,8 +101,8 @@ public override object FromEditor(ContentPropertyData editorValue, object curren
// Parse the HTML
var html = rte.Value?.ToString();
- var parseAndSavedTempImages = TemplateUtilities.FindAndPersistPastedTempImages(html, mediaParentId, userId, _mediaService, _contentTypeBaseServiceProvider, _logger);
- var editorValueWithMediaUrlsRemoved = TemplateUtilities.RemoveMediaUrlsFromTextString(parseAndSavedTempImages);
+ var parseAndSavedTempImages = _mediaParser.FindAndPersistPastedTempImages(html, mediaParentId, userId);
+ var editorValueWithMediaUrlsRemoved = _mediaParser.RemoveImageSources(parseAndSavedTempImages);
rte.Value = editorValueWithMediaUrlsRemoved;
}
@@ -127,7 +131,7 @@ public override object ToEditor(Property property, IDataTypeService dataTypeServ
{
var html = rte.Value?.ToString();
- var propertyValueWithMediaResolved = TemplateUtilities.ResolveMediaFromTextString(html);
+ var propertyValueWithMediaResolved = _mediaParser.EnsureImageSources(html);
rte.Value = propertyValueWithMediaResolved;
}
diff --git a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs
index 3eed40c8bf81..03dc7b669425 100644
--- a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs
@@ -24,27 +24,24 @@ namespace Umbraco.Web.PropertyEditors
Icon = "icon-browser-window")]
public class RichTextPropertyEditor : DataEditor
{
- private IMediaService _mediaService;
- private IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider;
private IUmbracoContextAccessor _umbracoContextAccessor;
- private ILogger _logger;
+ private readonly MediaParser _mediaParser;
///
/// The constructor will setup the property editor based on the attribute if one is found
///
- public RichTextPropertyEditor(ILogger logger, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor) : base(logger)
+ public RichTextPropertyEditor(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor, MediaParser mediaParser)
+ : base(logger)
{
- _mediaService = mediaService;
- _contentTypeBaseServiceProvider = contentTypeBaseServiceProvider;
_umbracoContextAccessor = umbracoContextAccessor;
- _logger = logger;
+ _mediaParser = mediaParser;
}
///
/// Create a custom value editor
///
///
- protected override IDataValueEditor CreateValueEditor() => new RichTextPropertyValueEditor(Attribute, _mediaService, _contentTypeBaseServiceProvider, _umbracoContextAccessor, _logger);
+ protected override IDataValueEditor CreateValueEditor() => new RichTextPropertyValueEditor(Attribute, _umbracoContextAccessor, _mediaParser);
protected override IConfigurationEditor CreateConfigurationEditor() => new RichTextConfigurationEditor();
@@ -53,20 +50,16 @@ public RichTextPropertyEditor(ILogger logger, IMediaService mediaService, IConte
///
/// A custom value editor to ensure that macro syntax is parsed when being persisted and formatted correctly for display in the editor
///
- internal class RichTextPropertyValueEditor : DataValueEditor
+ internal class RichTextPropertyValueEditor : DataValueEditor, IDataValueReference
{
- private IMediaService _mediaService;
- private IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider;
private IUmbracoContextAccessor _umbracoContextAccessor;
- private ILogger _logger;
+ private readonly MediaParser _mediaParser;
- public RichTextPropertyValueEditor(DataEditorAttribute attribute, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor, ILogger logger)
+ public RichTextPropertyValueEditor(DataEditorAttribute attribute, IUmbracoContextAccessor umbracoContextAccessor, MediaParser _mediaParser)
: base(attribute)
{
- _mediaService = mediaService;
- _contentTypeBaseServiceProvider = contentTypeBaseServiceProvider;
_umbracoContextAccessor = umbracoContextAccessor;
- _logger = logger;
+ this._mediaParser = _mediaParser;
}
///
@@ -98,7 +91,7 @@ public override object ToEditor(Property property, IDataTypeService dataTypeServ
if (val == null)
return null;
- var propertyValueWithMediaResolved = TemplateUtilities.ResolveMediaFromTextString(val.ToString());
+ var propertyValueWithMediaResolved = _mediaParser.EnsureImageSources(val.ToString());
var parsed = MacroTagParser.FormatRichTextPersistedDataForEditor(propertyValueWithMediaResolved, new Dictionary());
return parsed;
}
@@ -120,12 +113,22 @@ public override object FromEditor(Core.Models.Editors.ContentPropertyData editor
var mediaParent = config?.MediaParentId;
var mediaParentId = mediaParent == null ? Guid.Empty : mediaParent.Guid;
- var parseAndSavedTempImages = TemplateUtilities.FindAndPersistPastedTempImages(editorValue.Value.ToString(), mediaParentId, userId, _mediaService, _contentTypeBaseServiceProvider, _logger);
- var editorValueWithMediaUrlsRemoved = TemplateUtilities.RemoveMediaUrlsFromTextString(parseAndSavedTempImages);
+ var parseAndSavedTempImages = _mediaParser.FindAndPersistPastedTempImages(editorValue.Value.ToString(), mediaParentId, userId);
+ var editorValueWithMediaUrlsRemoved = _mediaParser.RemoveImageSources(parseAndSavedTempImages);
var parsed = MacroTagParser.FormatRichTextContentForPersistence(editorValueWithMediaUrlsRemoved);
return parsed;
}
+
+ ///
+ /// Resolve references from values
+ ///
+ ///
+ ///
+ public IEnumerable GetReferences(object value)
+ {
+ throw new NotImplementedException();
+ }
}
internal class RichTextPropertyIndexValueFactory : IPropertyIndexValueFactory
diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs
index 98413c7b7088..578a4cad065f 100644
--- a/src/Umbraco.Web/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs
+++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs
@@ -13,10 +13,12 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
public class MarkdownEditorValueConverter : PropertyValueConverterBase
{
private readonly InternalLinkParser _localLinkParser;
+ private readonly UrlParser _urlResolver;
- public MarkdownEditorValueConverter(InternalLinkParser localLinkParser)
+ public MarkdownEditorValueConverter(InternalLinkParser localLinkParser, UrlParser urlResolver)
{
_localLinkParser = localLinkParser;
+ _urlResolver = urlResolver;
}
public override bool IsConverter(IPublishedPropertyType propertyType)
@@ -34,8 +36,8 @@ public override object ConvertSourceToIntermediate(IPublishedElement owner, IPub
var sourceString = source.ToString();
// ensures string is parsed for {localLink} and urls are resolved correctly
- sourceString = _localLinkParser.ParseInternalLinks(sourceString, preview);
- sourceString = TemplateUtilities.ResolveUrlsFromTextString(sourceString);
+ sourceString = _localLinkParser.EnsureInternalLinks(sourceString, preview);
+ sourceString = _urlResolver.EnsureUrls(sourceString);
return sourceString;
}
diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs
index 95cf2cfc855e..88c1429b1600 100644
--- a/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs
+++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs
@@ -25,6 +25,8 @@ public class RteMacroRenderingValueConverter : TinyMceValueConverter
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
private readonly IMacroRenderer _macroRenderer;
private readonly InternalLinkParser _internalLinkParser;
+ private readonly UrlParser _urlResolver;
+ private readonly MediaParser _mediaParser;
public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType)
{
@@ -33,11 +35,14 @@ public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType
return PropertyCacheLevel.Snapshot;
}
- public RteMacroRenderingValueConverter(IUmbracoContextAccessor umbracoContextAccessor, IMacroRenderer macroRenderer, InternalLinkParser internalLinkParser)
+ public RteMacroRenderingValueConverter(IUmbracoContextAccessor umbracoContextAccessor, IMacroRenderer macroRenderer,
+ InternalLinkParser internalLinkParser, UrlParser urlResolver, MediaParser mediaParser)
{
_umbracoContextAccessor = umbracoContextAccessor;
_macroRenderer = macroRenderer;
_internalLinkParser = internalLinkParser;
+ _urlResolver = urlResolver;
+ _mediaParser = mediaParser;
}
// NOT thread-safe over a request because it modifies the
@@ -83,9 +88,9 @@ private string Convert(object source, bool preview)
var sourceString = source.ToString();
// ensures string is parsed for {localLink} and urls and media are resolved correctly
- sourceString = _internalLinkParser.ParseInternalLinks(sourceString, preview);
- sourceString = TemplateUtilities.ResolveUrlsFromTextString(sourceString);
- sourceString = TemplateUtilities.ResolveMediaFromTextString(sourceString);
+ sourceString = _internalLinkParser.EnsureInternalLinks(sourceString, preview);
+ sourceString = _urlResolver.EnsureUrls(sourceString);
+ sourceString = _mediaParser.EnsureImageSources(sourceString);
// ensure string is parsed for macros and macros are executed correctly
sourceString = RenderRteMacros(sourceString, preview);
diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/TextStringValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/TextStringValueConverter.cs
index ee49536d9d72..1b85d6e608de 100644
--- a/src/Umbraco.Web/PropertyEditors/ValueConverters/TextStringValueConverter.cs
+++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/TextStringValueConverter.cs
@@ -11,9 +11,10 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
[DefaultPropertyValueConverter]
public class TextStringValueConverter : PropertyValueConverterBase
{
- public TextStringValueConverter(InternalLinkParser internalLinkParser)
+ public TextStringValueConverter(InternalLinkParser internalLinkParser, UrlParser urlParser)
{
_internalLinkParser = internalLinkParser;
+ _urlParser = urlParser;
}
private static readonly string[] PropertyTypeAliases =
@@ -22,6 +23,7 @@ public TextStringValueConverter(InternalLinkParser internalLinkParser)
Constants.PropertyEditors.Aliases.TextArea
};
private readonly InternalLinkParser _internalLinkParser;
+ private readonly UrlParser _urlParser;
public override bool IsConverter(IPublishedPropertyType propertyType)
=> PropertyTypeAliases.Contains(propertyType.EditorAlias);
@@ -38,8 +40,8 @@ public override object ConvertSourceToIntermediate(IPublishedElement owner, IPub
var sourceString = source.ToString();
// ensures string is parsed for {localLink} and urls are resolved correctly
- sourceString = _internalLinkParser.ParseInternalLinks(sourceString, preview);
- sourceString = TemplateUtilities.ResolveUrlsFromTextString(sourceString);
+ sourceString = _internalLinkParser.EnsureInternalLinks(sourceString, preview);
+ sourceString = _urlParser.EnsureUrls(sourceString);
return sourceString;
}
diff --git a/src/Umbraco.Web/Runtime/WebInitialComposer.cs b/src/Umbraco.Web/Runtime/WebInitialComposer.cs
index 82137bbd9d68..1b3128388dcf 100644
--- a/src/Umbraco.Web/Runtime/WebInitialComposer.cs
+++ b/src/Umbraco.Web/Runtime/WebInitialComposer.cs
@@ -108,6 +108,8 @@ public override void Compose(Composition composition)
composition.RegisterUnique();
composition.RegisterUnique();
+ composition.RegisterUnique();
+ composition.RegisterUnique();
// register the umbraco helper - this is Transient! very important!
// also, if not level.Run, we cannot really use the helper (during upgrade...)
diff --git a/src/Umbraco.Web/Templates/InternalLinkParser.cs b/src/Umbraco.Web/Templates/InternalLinkParser.cs
index 0d8a480a9048..32d7d42eac3f 100644
--- a/src/Umbraco.Web/Templates/InternalLinkParser.cs
+++ b/src/Umbraco.Web/Templates/InternalLinkParser.cs
@@ -23,17 +23,23 @@ public InternalLinkParser(IUmbracoContextAccessor umbracoContextAccessor)
_umbracoContextAccessor = umbracoContextAccessor;
}
- public string ParseInternalLinks(string text, bool preview)
+ ///
+ /// Parses the string looking for the {localLink} syntax and updates them to their correct links.
+ ///
+ ///
+ ///
+ ///
+ public string EnsureInternalLinks(string text, bool preview)
{
if (_umbracoContextAccessor.UmbracoContext == null)
throw new InvalidOperationException("Could not parse internal links, there is no current UmbracoContext");
if (!preview)
- return ParseInternalLinks(text);
+ return EnsureInternalLinks(text);
using (_umbracoContextAccessor.UmbracoContext.ForcedPreview(preview)) // force for url provider
{
- return ParseInternalLinks(text);
+ return EnsureInternalLinks(text);
}
}
@@ -43,7 +49,7 @@ public string ParseInternalLinks(string text, bool preview)
///
///
///
- public string ParseInternalLinks(string text)
+ public string EnsureInternalLinks(string text)
{
if (_umbracoContextAccessor.UmbracoContext == null)
throw new InvalidOperationException("Could not parse internal links, there is no current UmbracoContext");
diff --git a/src/Umbraco.Web/Templates/MediaParser.cs b/src/Umbraco.Web/Templates/MediaParser.cs
new file mode 100644
index 000000000000..9a3f8def3c52
--- /dev/null
+++ b/src/Umbraco.Web/Templates/MediaParser.cs
@@ -0,0 +1,186 @@
+using HtmlAgilityPack;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text.RegularExpressions;
+using Umbraco.Core;
+using Umbraco.Core.Exceptions;
+using Umbraco.Core.IO;
+using Umbraco.Core.Logging;
+using Umbraco.Core.Models;
+using Umbraco.Core.Services;
+
+namespace Umbraco.Web.Templates
+{
+ public sealed class MediaParser
+ {
+ public MediaParser(IUmbracoContextAccessor umbracoContextAccessor, ILogger logger, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider)
+ {
+ _umbracoContextAccessor = umbracoContextAccessor;
+ _logger = logger;
+ _mediaService = mediaService;
+ _contentTypeBaseServiceProvider = contentTypeBaseServiceProvider;
+ }
+
+ private static readonly Regex ResolveImgPattern = new Regex(@"(]*src="")([^""\?]*)([^""]*""[^>]*data-udi="")([^""]*)(""[^>]*>)",
+ RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
+ private readonly IUmbracoContextAccessor _umbracoContextAccessor;
+ private readonly ILogger _logger;
+ private readonly IMediaService _mediaService;
+ private readonly IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider;
+ const string TemporaryImageDataAttribute = "data-tmpimg";
+
+ ///
+ /// Parses the string looking for Umbraco image tags and updates them to their up-to-date image sources.
+ ///
+ ///
+ ///
+ /// Umbraco image tags are identified by their data-udi attributes
+ public string EnsureImageSources(string text)
+ {
+ // don't attempt to proceed without a context
+ if (_umbracoContextAccessor?.UmbracoContext?.Media == null)
+ {
+ return text;
+ }
+
+ return ResolveImgPattern.Replace(text, match =>
+ {
+ // match groups:
+ // - 1 = from the beginning of the image tag until src attribute value begins
+ // - 2 = the src attribute value excluding the querystring (if present)
+ // - 3 = anything after group 2 and before the data-udi attribute value begins
+ // - 4 = the data-udi attribute value
+ // - 5 = anything after group 4 until the image tag is closed
+ var udi = match.Groups[4].Value;
+ if (udi.IsNullOrWhiteSpace() || GuidUdi.TryParse(udi, out var guidUdi) == false)
+ {
+ return match.Value;
+ }
+ var media = _umbracoContextAccessor?.UmbracoContext?.Media.GetById(guidUdi.Guid);
+ if (media == null)
+ {
+ // image does not exist - we could choose to remove the image entirely here (return empty string),
+ // but that would leave the editors completely in the dark as to why the image doesn't show
+ return match.Value;
+ }
+
+ var url = media.Url;
+ return $"{match.Groups[1].Value}{url}{match.Groups[3].Value}{udi}{match.Groups[5].Value}";
+ });
+ }
+
+ ///
+ /// Removes media urls from <img> tags where a data-udi attribute is present
+ ///
+ ///
+ ///
+ internal string RemoveImageSources(string text)
+ // see comment in ResolveMediaFromTextString for group reference
+ => ResolveImgPattern.Replace(text, "$1$3$4$5");
+
+ internal string FindAndPersistPastedTempImages(string html, Guid mediaParentFolder, int userId)
+ {
+ // Find all img's that has data-tmpimg attribute
+ // Use HTML Agility Pack - https://html-agility-pack.net
+ var htmlDoc = new HtmlDocument();
+ htmlDoc.LoadHtml(html);
+
+ var tmpImages = htmlDoc.DocumentNode.SelectNodes($"//img[@{TemporaryImageDataAttribute}]");
+ if (tmpImages == null || tmpImages.Count == 0)
+ return html;
+
+ // An array to contain a list of URLs that
+ // we have already processed to avoid dupes
+ var uploadedImages = new Dictionary();
+
+ foreach (var img in tmpImages)
+ {
+ // The data attribute contains the path to the tmp img to persist as a media item
+ var tmpImgPath = img.GetAttributeValue(TemporaryImageDataAttribute, string.Empty);
+
+ if (string.IsNullOrEmpty(tmpImgPath))
+ continue;
+
+ var absoluteTempImagePath = IOHelper.MapPath(tmpImgPath);
+ var fileName = Path.GetFileName(absoluteTempImagePath);
+ var safeFileName = fileName.ToSafeFileName();
+
+ var mediaItemName = safeFileName.ToFriendlyName();
+ IMedia mediaFile;
+ GuidUdi udi;
+
+ if (uploadedImages.ContainsKey(tmpImgPath) == false)
+ {
+ if (mediaParentFolder == Guid.Empty)
+ mediaFile = _mediaService.CreateMedia(mediaItemName, Constants.System.Root, Constants.Conventions.MediaTypes.Image, userId);
+ else
+ mediaFile = _mediaService.CreateMedia(mediaItemName, mediaParentFolder, Constants.Conventions.MediaTypes.Image, userId);
+
+ var fileInfo = new FileInfo(absoluteTempImagePath);
+
+ var fileStream = fileInfo.OpenReadWithRetry();
+ if (fileStream == null) throw new InvalidOperationException("Could not acquire file stream");
+ using (fileStream)
+ {
+ mediaFile.SetValue(_contentTypeBaseServiceProvider, Constants.Conventions.Media.File, safeFileName, fileStream);
+ }
+
+ _mediaService.Save(mediaFile, userId);
+
+ udi = mediaFile.GetUdi();
+ }
+ else
+ {
+ // Already been uploaded & we have it's UDI
+ udi = uploadedImages[tmpImgPath];
+ }
+
+ // Add the UDI to the img element as new data attribute
+ img.SetAttributeValue("data-udi", udi.ToString());
+
+ // Get the new persisted image url
+ var mediaTyped = _umbracoContextAccessor?.UmbracoContext?.Media.GetById(udi.Guid);
+ if (mediaTyped == null)
+ throw new PanicException($"Could not find media by id {udi.Guid} or there was no UmbracoContext available.");
+
+ var location = mediaTyped.Url;
+
+ // Find the width & height attributes as we need to set the imageprocessor QueryString
+ var width = img.GetAttributeValue("width", int.MinValue);
+ var height = img.GetAttributeValue("height", int.MinValue);
+
+ if (width != int.MinValue && height != int.MinValue)
+ {
+ location = $"{location}?width={width}&height={height}&mode=max";
+ }
+
+ img.SetAttributeValue("src", location);
+
+ // Remove the data attribute (so we do not re-process this)
+ img.Attributes.Remove(TemporaryImageDataAttribute);
+
+ // Add to the dictionary to avoid dupes
+ if (uploadedImages.ContainsKey(tmpImgPath) == false)
+ {
+ uploadedImages.Add(tmpImgPath, udi);
+
+ // Delete folder & image now its saved in media
+ // The folder should contain one image - as a unique guid folder created
+ // for each image uploaded from TinyMceController
+ var folderName = Path.GetDirectoryName(absoluteTempImagePath);
+ try
+ {
+ Directory.Delete(folderName, true);
+ }
+ catch (Exception ex)
+ {
+ _logger.Error(typeof(MediaParser), ex, "Could not delete temp file or folder {FileName}", absoluteTempImagePath);
+ }
+ }
+ }
+
+ return htmlDoc.DocumentNode.OuterHtml;
+ }
+ }
+}
diff --git a/src/Umbraco.Web/Templates/TemplateUtilities.cs b/src/Umbraco.Web/Templates/TemplateUtilities.cs
index 1092be73e24f..d4bae3814726 100644
--- a/src/Umbraco.Web/Templates/TemplateUtilities.cs
+++ b/src/Umbraco.Web/Templates/TemplateUtilities.cs
@@ -2,7 +2,6 @@
using System;
using System.Collections.Generic;
using System.IO;
-using System.Text.RegularExpressions;
using Umbraco.Core;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
@@ -16,19 +15,9 @@
namespace Umbraco.Web.Templates
{
- ///
- /// Utility class used for templates
- ///
+ [Obsolete("This class is obsolete, all methods have been moved to other classes such as InternalLinkHelper, UrlResolver and MediaParser")]
public static class TemplateUtilities
{
- const string TemporaryImageDataAttribute = "data-tmpimg";
-
- private static readonly Regex ResolveUrlPattern = new Regex("(=[\"\']?)(\\W?\\~(?:.(?![\"\']?\\s+(?:\\S+)=|[>\"\']))+.)[\"\']?",
- RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
-
- private static readonly Regex ResolveImgPattern = new Regex(@"(]*src="")([^""\?]*)([^""]*""[^>]*data-udi="")([^""]*)(""[^>]*>)",
- RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
-
[Obsolete("Inject and use an instance of InternalLinkParser instead")]
internal static string ParseInternalLinks(string text, bool preview, UmbracoContext umbracoContext)
{
@@ -41,201 +30,27 @@ internal static string ParseInternalLinks(string text, bool preview, UmbracoCont
}
[Obsolete("Inject and use an instance of InternalLinkParser instead")]
- public static string ParseInternalLinks(string text, UrlProvider urlProvider) =>
- Current.Factory.GetInstance().ParseInternalLinks(text);
+ public static string ParseInternalLinks(string text, UrlProvider urlProvider)
+ => Current.Factory.GetInstance().EnsureInternalLinks(text);
- ///
- /// The RegEx matches any HTML attribute values that start with a tilde (~), those that match are passed to ResolveUrl to replace the tilde with the application path.
- ///
- ///
- ///
- ///
- /// When used with a Virtual-Directory set-up, this would resolve all URLs correctly.
- /// The recommendation is that the "ResolveUrlsFromTextString" option (in umbracoSettings.config) is set to false for non-Virtual-Directory installs.
- ///
+ [Obsolete("Inject and use an instance of UrlResolver")]
public static string ResolveUrlsFromTextString(string text)
- {
- if (Current.Configs.Settings().Content.ResolveUrlsFromTextString == false) return text;
-
- using (var timer = Current.ProfilingLogger.DebugDuration(typeof(IOHelper), "ResolveUrlsFromTextString starting", "ResolveUrlsFromTextString complete"))
- {
- // find all relative urls (ie. urls that contain ~)
- var tags = ResolveUrlPattern.Matches(text);
- Current.Logger.Debug(typeof(IOHelper), "After regex: {Duration} matched: {TagsCount}", timer.Stopwatch.ElapsedMilliseconds, tags.Count);
- foreach (Match tag in tags)
- {
- var url = "";
- if (tag.Groups[1].Success)
- url = tag.Groups[1].Value;
-
- // The richtext editor inserts a slash in front of the url. That's why we need this little fix
- // if (url.StartsWith("/"))
- // text = text.Replace(url, ResolveUrl(url.Substring(1)));
- // else
- if (String.IsNullOrEmpty(url) == false)
- {
- var resolvedUrl = (url.Substring(0, 1) == "/") ? IOHelper.ResolveUrl(url.Substring(1)) : IOHelper.ResolveUrl(url);
- text = text.Replace(url, resolvedUrl);
- }
- }
- }
-
- return text;
- }
+ => Current.Factory.GetInstance().EnsureUrls(text);
+ [Obsolete("Use StringExtensions.CleanForXss instead")]
public static string CleanForXss(string text, params char[] ignoreFromClean)
- {
- return text.CleanForXss(ignoreFromClean);
- }
+ => text.CleanForXss(ignoreFromClean);
- ///
- /// Parses the string looking for Umbraco image tags and updates them to their up-to-date image sources.
- ///
- ///
- ///
- /// Umbraco image tags are identified by their data-udi attributes
+ [Obsolete("Use MediaParser.EnsureImageSources instead")]
public static string ResolveMediaFromTextString(string text)
- {
- // don't attempt to proceed without a context
- if (Current.UmbracoContext == null || Current.UmbracoContext.Media == null)
- {
- return text;
- }
-
- return ResolveImgPattern.Replace(text, match =>
- {
- // match groups:
- // - 1 = from the beginning of the image tag until src attribute value begins
- // - 2 = the src attribute value excluding the querystring (if present)
- // - 3 = anything after group 2 and before the data-udi attribute value begins
- // - 4 = the data-udi attribute value
- // - 5 = anything after group 4 until the image tag is closed
- var udi = match.Groups[4].Value;
- if(udi.IsNullOrWhiteSpace() || GuidUdi.TryParse(udi, out var guidUdi) == false)
- {
- return match.Value;
- }
- var media = Current.UmbracoContext.Media.GetById(guidUdi.Guid);
- if(media == null)
- {
- // image does not exist - we could choose to remove the image entirely here (return empty string),
- // but that would leave the editors completely in the dark as to why the image doesn't show
- return match.Value;
- }
-
- var url = media.Url;
- return $"{match.Groups[1].Value}{url}{match.Groups[3].Value}{udi}{match.Groups[5].Value}";
- });
- }
-
- ///
- /// Removes media urls from <img> tags where a data-udi attribute is present
- ///
- ///
- ///
+ => Current.Factory.GetInstance().EnsureImageSources(text);
+
+ [Obsolete("Use MediaParser.RemoveImageSources instead")]
internal static string RemoveMediaUrlsFromTextString(string text)
- // see comment in ResolveMediaFromTextString for group reference
- => ResolveImgPattern.Replace(text, "$1$3$4$5");
+ => Current.Factory.GetInstance().RemoveImageSources(text);
+ [Obsolete("Use MediaParser.RemoveImageSources instead")]
internal static string FindAndPersistPastedTempImages(string html, Guid mediaParentFolder, int userId, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, ILogger logger)
- {
- // Find all img's that has data-tmpimg attribute
- // Use HTML Agility Pack - https://html-agility-pack.net
- var htmlDoc = new HtmlDocument();
- htmlDoc.LoadHtml(html);
-
- var tmpImages = htmlDoc.DocumentNode.SelectNodes($"//img[@{TemporaryImageDataAttribute}]");
- if (tmpImages == null || tmpImages.Count == 0)
- return html;
-
- // An array to contain a list of URLs that
- // we have already processed to avoid dupes
- var uploadedImages = new Dictionary();
-
- foreach (var img in tmpImages)
- {
- // The data attribute contains the path to the tmp img to persist as a media item
- var tmpImgPath = img.GetAttributeValue(TemporaryImageDataAttribute, string.Empty);
-
- if (string.IsNullOrEmpty(tmpImgPath))
- continue;
-
- var absoluteTempImagePath = IOHelper.MapPath(tmpImgPath);
- var fileName = Path.GetFileName(absoluteTempImagePath);
- var safeFileName = fileName.ToSafeFileName();
-
- var mediaItemName = safeFileName.ToFriendlyName();
- IMedia mediaFile;
- GuidUdi udi;
-
- if (uploadedImages.ContainsKey(tmpImgPath) == false)
- {
- if (mediaParentFolder == Guid.Empty)
- mediaFile = mediaService.CreateMedia(mediaItemName, Constants.System.Root, Constants.Conventions.MediaTypes.Image, userId);
- else
- mediaFile = mediaService.CreateMedia(mediaItemName, mediaParentFolder, Constants.Conventions.MediaTypes.Image, userId);
-
- var fileInfo = new FileInfo(absoluteTempImagePath);
-
- var fileStream = fileInfo.OpenReadWithRetry();
- if (fileStream == null) throw new InvalidOperationException("Could not acquire file stream");
- using (fileStream)
- {
- mediaFile.SetValue(contentTypeBaseServiceProvider, Constants.Conventions.Media.File, safeFileName, fileStream);
- }
-
- mediaService.Save(mediaFile, userId);
-
- udi = mediaFile.GetUdi();
- }
- else
- {
- // Already been uploaded & we have it's UDI
- udi = uploadedImages[tmpImgPath];
- }
-
- // Add the UDI to the img element as new data attribute
- img.SetAttributeValue("data-udi", udi.ToString());
-
- // Get the new persisted image url
- var mediaTyped = Current.UmbracoHelper.Media(udi.Guid);
- var location = mediaTyped.Url;
-
- // Find the width & height attributes as we need to set the imageprocessor QueryString
- var width = img.GetAttributeValue("width", int.MinValue);
- var height = img.GetAttributeValue("height", int.MinValue);
-
- if(width != int.MinValue && height != int.MinValue)
- {
- location = $"{location}?width={width}&height={height}&mode=max";
- }
-
- img.SetAttributeValue("src", location);
-
- // Remove the data attribute (so we do not re-process this)
- img.Attributes.Remove(TemporaryImageDataAttribute);
-
- // Add to the dictionary to avoid dupes
- if(uploadedImages.ContainsKey(tmpImgPath) == false)
- {
- uploadedImages.Add(tmpImgPath, udi);
-
- // Delete folder & image now its saved in media
- // The folder should contain one image - as a unique guid folder created
- // for each image uploaded from TinyMceController
- var folderName = Path.GetDirectoryName(absoluteTempImagePath);
- try
- {
- Directory.Delete(folderName, true);
- }
- catch (Exception ex)
- {
- logger.Error(typeof(TemplateUtilities), ex, "Could not delete temp file or folder {FileName}", absoluteTempImagePath);
- }
- }
- }
-
- return htmlDoc.DocumentNode.OuterHtml;
- }
+ => Current.Factory.GetInstance().FindAndPersistPastedTempImages(html, mediaParentFolder, userId);
}
}
diff --git a/src/Umbraco.Web/Templates/UrlParser.cs b/src/Umbraco.Web/Templates/UrlParser.cs
new file mode 100644
index 000000000000..e5c40b73655d
--- /dev/null
+++ b/src/Umbraco.Web/Templates/UrlParser.cs
@@ -0,0 +1,61 @@
+using System.Text.RegularExpressions;
+using Umbraco.Core.Configuration.UmbracoSettings;
+using Umbraco.Core.IO;
+using Umbraco.Core.Logging;
+
+namespace Umbraco.Web.Templates
+{
+ public sealed class UrlParser
+ {
+ private readonly IContentSection _contentSection;
+ private readonly IProfilingLogger _logger;
+
+ private static readonly Regex ResolveUrlPattern = new Regex("(=[\"\']?)(\\W?\\~(?:.(?![\"\']?\\s+(?:\\S+)=|[>\"\']))+.)[\"\']?",
+ RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
+
+ public UrlParser(IContentSection contentSection, IProfilingLogger logger)
+ {
+ _contentSection = contentSection;
+ _logger = logger;
+ }
+
+ ///
+ /// The RegEx matches any HTML attribute values that start with a tilde (~), those that match are passed to ResolveUrl to replace the tilde with the application path.
+ ///
+ ///
+ ///
+ ///
+ /// When used with a Virtual-Directory set-up, this would resolve all URLs correctly.
+ /// The recommendation is that the "ResolveUrlsFromTextString" option (in umbracoSettings.config) is set to false for non-Virtual-Directory installs.
+ ///
+ public string EnsureUrls(string text)
+ {
+ if (_contentSection.ResolveUrlsFromTextString == false) return text;
+
+ using (var timer = _logger.DebugDuration(typeof(IOHelper), "ResolveUrlsFromTextString starting", "ResolveUrlsFromTextString complete"))
+ {
+ // find all relative urls (ie. urls that contain ~)
+ var tags = ResolveUrlPattern.Matches(text);
+ _logger.Debug(typeof(IOHelper), "After regex: {Duration} matched: {TagsCount}", timer.Stopwatch.ElapsedMilliseconds, tags.Count);
+ foreach (Match tag in tags)
+ {
+ var url = "";
+ if (tag.Groups[1].Success)
+ url = tag.Groups[1].Value;
+
+ // The richtext editor inserts a slash in front of the url. That's why we need this little fix
+ // if (url.StartsWith("/"))
+ // text = text.Replace(url, ResolveUrl(url.Substring(1)));
+ // else
+ if (string.IsNullOrEmpty(url) == false)
+ {
+ var resolvedUrl = (url.Substring(0, 1) == "/") ? IOHelper.ResolveUrl(url.Substring(1)) : IOHelper.ResolveUrl(url);
+ text = text.Replace(url, resolvedUrl);
+ }
+ }
+ }
+
+ return text;
+ }
+ }
+}
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 616ed908e104..74ac3f65f397 100755
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -248,6 +248,8 @@
+
+
diff --git a/src/Umbraco.Web/UmbracoComponentRenderer.cs b/src/Umbraco.Web/UmbracoComponentRenderer.cs
index 805b9267f92e..c0f83fd1af3e 100644
--- a/src/Umbraco.Web/UmbracoComponentRenderer.cs
+++ b/src/Umbraco.Web/UmbracoComponentRenderer.cs
@@ -159,7 +159,7 @@ private IHtmlString RenderMacro(string alias, IDictionary parame
_umbracoContextAccessor.UmbracoContext.HttpContext.Response.ContentType = contentType;
//Now, we need to ensure that local links are parsed
- html = _internalLinkParser.ParseInternalLinks(output.ToString());
+ html = _internalLinkParser.EnsureInternalLinks(output.ToString());
}
}
From f8e04eb1d624fbefcb39b889a2babeb7bbe255bb Mon Sep 17 00:00:00 2001
From: Shannon
Date: Tue, 22 Oct 2019 00:53:52 +1100
Subject: [PATCH 06/15] Adds tests for MediaParser and simplifies
UmbracoContext mocking
---
.../PropertyEditors/ImageCropperTest.cs | 1 +
.../Testing/Objects/TestDataSource.cs | 3 +
.../Objects/TestUmbracoContextFactory.cs | 49 ++++++++++
src/Umbraco.Tests/Umbraco.Tests.csproj | 2 +
.../Web/InternalLinkParserTests.cs | 46 ++++-----
src/Umbraco.Tests/Web/MediaParserTests.cs | 97 +++++++++++++++++++
src/Umbraco.Web/Templates/MediaParser.cs | 12 ++-
7 files changed, 176 insertions(+), 34 deletions(-)
create mode 100644 src/Umbraco.Tests/Testing/Objects/TestUmbracoContextFactory.cs
create mode 100644 src/Umbraco.Tests/Web/MediaParserTests.cs
diff --git a/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs b/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs
index 8d2ab84d3524..433ba64b386c 100644
--- a/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs
+++ b/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs
@@ -24,6 +24,7 @@
namespace Umbraco.Tests.PropertyEditors
{
+
[TestFixture]
public class ImageCropperTest
{
diff --git a/src/Umbraco.Tests/Testing/Objects/TestDataSource.cs b/src/Umbraco.Tests/Testing/Objects/TestDataSource.cs
index 0291715e460e..4476a7464e10 100644
--- a/src/Umbraco.Tests/Testing/Objects/TestDataSource.cs
+++ b/src/Umbraco.Tests/Testing/Objects/TestDataSource.cs
@@ -1,12 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Scoping;
+using Umbraco.Web;
using Umbraco.Web.PublishedCache.NuCache;
using Umbraco.Web.PublishedCache.NuCache.DataSource;
namespace Umbraco.Tests.Testing.Objects
{
+
internal class TestDataSource : IDataSource
{
public TestDataSource(params ContentNodeKit[] kits)
diff --git a/src/Umbraco.Tests/Testing/Objects/TestUmbracoContextFactory.cs b/src/Umbraco.Tests/Testing/Objects/TestUmbracoContextFactory.cs
new file mode 100644
index 000000000000..7f891a258024
--- /dev/null
+++ b/src/Umbraco.Tests/Testing/Objects/TestUmbracoContextFactory.cs
@@ -0,0 +1,49 @@
+using Moq;
+using Umbraco.Core.Configuration;
+using Umbraco.Core.Configuration.UmbracoSettings;
+using Umbraco.Core.Services;
+using Umbraco.Tests.TestHelpers;
+using Umbraco.Tests.Testing.Objects.Accessors;
+using Umbraco.Web;
+using Umbraco.Web.PublishedCache;
+using Umbraco.Web.Routing;
+
+namespace Umbraco.Tests.Testing.Objects
+{
+ ///
+ /// Simplify creating test UmbracoContext's
+ ///
+ public class TestUmbracoContextFactory
+ {
+ public static IUmbracoContextFactory Create(IGlobalSettings globalSettings = null, IUrlProvider urlProvider = null,
+ IMediaUrlProvider mediaUrlProvider = null,
+ IUmbracoContextAccessor umbracoContextAccessor = null)
+ {
+ if (globalSettings == null) globalSettings = SettingsForTests.GenerateMockGlobalSettings();
+ if (urlProvider == null) urlProvider = Mock.Of();
+ if (mediaUrlProvider == null) mediaUrlProvider = Mock.Of();
+ if (umbracoContextAccessor == null) umbracoContextAccessor = new TestUmbracoContextAccessor();
+
+ var contentCache = new Mock();
+ var mediaCache = new Mock();
+ var snapshot = new Mock();
+ snapshot.Setup(x => x.Content).Returns(contentCache.Object);
+ snapshot.Setup(x => x.Media).Returns(mediaCache.Object);
+ var snapshotService = new Mock();
+ snapshotService.Setup(x => x.CreatePublishedSnapshot(It.IsAny())).Returns(snapshot.Object);
+
+ var umbracoContextFactory = new UmbracoContextFactory(
+ umbracoContextAccessor,
+ snapshotService.Object,
+ new TestVariationContextAccessor(),
+ new TestDefaultCultureAccessor(),
+ Mock.Of(section => section.WebRouting == Mock.Of(routingSection => routingSection.UrlProviderMode == "Auto")),
+ globalSettings,
+ new UrlProviderCollection(new[] { urlProvider }),
+ new MediaUrlProviderCollection(new[] { mediaUrlProvider }),
+ Mock.Of());
+
+ return umbracoContextFactory;
+ }
+ }
+}
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index e73caf45171a..20b29a31471d 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -212,6 +212,7 @@
+
@@ -254,6 +255,7 @@
+
diff --git a/src/Umbraco.Tests/Web/InternalLinkParserTests.cs b/src/Umbraco.Tests/Web/InternalLinkParserTests.cs
index 6cdff240b8a4..0a948a861762 100644
--- a/src/Umbraco.Tests/Web/InternalLinkParserTests.cs
+++ b/src/Umbraco.Tests/Web/InternalLinkParserTests.cs
@@ -8,6 +8,7 @@
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Services;
using Umbraco.Tests.TestHelpers;
+using Umbraco.Tests.Testing.Objects;
using Umbraco.Tests.Testing.Objects.Accessors;
using Umbraco.Web;
using Umbraco.Web.PublishedCache;
@@ -16,6 +17,7 @@
namespace Umbraco.Tests.Web
{
+
[TestFixture]
public class InternalLinkParserTests
{
@@ -29,54 +31,40 @@ public class InternalLinkParserTests
[TestCase("hello href=\"{localLink:umb://document-type/9931BDE0-AAC3-4BAB-B838-909A7B47570E}\" world ", "hello href=\"#\" world ")]
public void ParseLocalLinks(string input, string result)
{
- var serviceCtxMock = new TestObjects(null).GetServiceContextMock();
-
//setup a mock url provider which we'll use for testing
- var testUrlProvider = new Mock();
- testUrlProvider
+ var contentUrlProvider = new Mock();
+ contentUrlProvider
.Setup(x => x.GetUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()))
.Returns(UrlInfo.Url("/my-test-url"));
-
- var globalSettings = SettingsForTests.GenerateMockGlobalSettings();
-
var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
var publishedContent = new Mock();
publishedContent.Setup(x => x.Id).Returns(1234);
publishedContent.Setup(x => x.ContentType).Returns(contentType);
- var contentCache = new Mock();
- contentCache.Setup(x => x.GetById(It.IsAny())).Returns(publishedContent.Object);
- contentCache.Setup(x => x.GetById(It.IsAny())).Returns(publishedContent.Object);
+
var mediaType = new PublishedContentType(777, "image", PublishedItemType.Media, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
var media = new Mock();
- media.Setup(x => x.Url).Returns("/media/1001/my-image.jpg");
media.Setup(x => x.ContentType).Returns(mediaType);
- var mediaCache = new Mock();
- mediaCache.Setup(x => x.GetById(It.IsAny())).Returns(media.Object);
- mediaCache.Setup(x => x.GetById(It.IsAny())).Returns(media.Object);
- var snapshot = new Mock();
- snapshot.Setup(x => x.Content).Returns(contentCache.Object);
- snapshot.Setup(x => x.Media).Returns(mediaCache.Object);
- var snapshotService = new Mock();
- snapshotService.Setup(x => x.CreatePublishedSnapshot(It.IsAny())).Returns(snapshot.Object);
var mediaUrlProvider = new Mock();
mediaUrlProvider.Setup(x => x.GetMediaUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()))
.Returns(UrlInfo.Url("/media/1001/my-image.jpg"));
var umbracoContextAccessor = new TestUmbracoContextAccessor();
- var umbracoContextFactory = new UmbracoContextFactory(
- umbracoContextAccessor,
- snapshotService.Object,
- new TestVariationContextAccessor(),
- new TestDefaultCultureAccessor(),
- Mock.Of(section => section.WebRouting == Mock.Of(routingSection => routingSection.UrlProviderMode == "Auto")),
- globalSettings,
- new UrlProviderCollection(new[] { testUrlProvider.Object }),
- new MediaUrlProviderCollection(new[] { mediaUrlProvider.Object }),
- Mock.Of());
+ var umbracoContextFactory = TestUmbracoContextFactory.Create(
+ urlProvider: contentUrlProvider.Object,
+ mediaUrlProvider: mediaUrlProvider.Object,
+ umbracoContextAccessor: umbracoContextAccessor);
using (var reference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of()))
{
+ var contentCache = Mock.Get(reference.UmbracoContext.Content);
+ contentCache.Setup(x => x.GetById(It.IsAny())).Returns(publishedContent.Object);
+ contentCache.Setup(x => x.GetById(It.IsAny())).Returns(publishedContent.Object);
+
+ var mediaCache = Mock.Get(reference.UmbracoContext.Media);
+ mediaCache.Setup(x => x.GetById(It.IsAny())).Returns(media.Object);
+ mediaCache.Setup(x => x.GetById(It.IsAny())).Returns(media.Object);
+
var linkParser = new InternalLinkParser(umbracoContextAccessor);
var output = linkParser.EnsureInternalLinks(input);
diff --git a/src/Umbraco.Tests/Web/MediaParserTests.cs b/src/Umbraco.Tests/Web/MediaParserTests.cs
new file mode 100644
index 000000000000..7c9e7576b585
--- /dev/null
+++ b/src/Umbraco.Tests/Web/MediaParserTests.cs
@@ -0,0 +1,97 @@
+using Umbraco.Core.Logging;
+using Moq;
+using NUnit.Framework;
+using Umbraco.Core.Services;
+using Umbraco.Tests.Testing.Objects.Accessors;
+using Umbraco.Web.Templates;
+using Umbraco.Web;
+using Umbraco.Core.Models.PublishedContent;
+using Umbraco.Web.Routing;
+using Umbraco.Tests.Testing.Objects;
+using System.Web;
+using System;
+using System.Linq;
+using Umbraco.Core.Models;
+
+namespace Umbraco.Tests.Web
+{
+ [TestFixture]
+ public class MediaParserTests
+ {
+ [Test]
+ public void Remove_Image_Sources()
+ {
+ var logger = Mock.Of();
+ var umbracoContextAccessor = new TestUmbracoContextAccessor();
+ var mediaParser = new MediaParser(umbracoContextAccessor, logger, Mock.Of(), Mock.Of());
+
+ var result = mediaParser.RemoveImageSources(@"
+
+
+
+
+
+");
+
+ Assert.AreEqual(@"
+
+
+
+
+
+", result);
+ }
+
+ [Test]
+ public void Ensure_Image_Sources()
+ {
+ //setup a mock url provider which we'll use for testing
+
+ var mediaType = new PublishedContentType(777, "image", PublishedItemType.Media, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
+ var media = new Mock();
+ media.Setup(x => x.ContentType).Returns(mediaType);
+ var mediaUrlProvider = new Mock();
+ mediaUrlProvider.Setup(x => x.GetMediaUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()))
+ .Returns(UrlInfo.Url("/media/1001/my-image.jpg"));
+
+ var umbracoContextAccessor = new TestUmbracoContextAccessor();
+
+ var umbracoContextFactory = TestUmbracoContextFactory.Create(
+ mediaUrlProvider: mediaUrlProvider.Object,
+ umbracoContextAccessor: umbracoContextAccessor);
+
+ using (var reference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of()))
+ {
+ var mediaCache = Mock.Get(reference.UmbracoContext.Media);
+ mediaCache.Setup(x => x.GetById(It.IsAny())).Returns(media.Object);
+
+ var mediaParser = new MediaParser(umbracoContextAccessor, Mock.Of(), Mock.Of(), Mock.Of());
+
+ var result = mediaParser.EnsureImageSources(@"
+
+
+
+
+
+
+
+
+");
+
+ Assert.AreEqual(@"
+
+
+
+
+
+
+
+
+", result);
+
+ }
+
+
+ }
+ }
+}
diff --git a/src/Umbraco.Web/Templates/MediaParser.cs b/src/Umbraco.Web/Templates/MediaParser.cs
index 9a3f8def3c52..4130b21da22b 100644
--- a/src/Umbraco.Web/Templates/MediaParser.cs
+++ b/src/Umbraco.Web/Templates/MediaParser.cs
@@ -9,6 +9,7 @@
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
+using Umbraco.Web.Routing;
namespace Umbraco.Web.Templates
{
@@ -39,11 +40,13 @@ public MediaParser(IUmbracoContextAccessor umbracoContextAccessor, ILogger logge
public string EnsureImageSources(string text)
{
// don't attempt to proceed without a context
- if (_umbracoContextAccessor?.UmbracoContext?.Media == null)
+ if (_umbracoContextAccessor?.UmbracoContext?.UrlProvider == null)
{
return text;
}
+ var urlProvider = _umbracoContextAccessor.UmbracoContext.UrlProvider;
+
return ResolveImgPattern.Replace(text, match =>
{
// match groups:
@@ -57,16 +60,15 @@ public string EnsureImageSources(string text)
{
return match.Value;
}
- var media = _umbracoContextAccessor?.UmbracoContext?.Media.GetById(guidUdi.Guid);
- if (media == null)
+ var mediaUrl = urlProvider.GetMediaUrl(guidUdi.Guid);
+ if (mediaUrl == null)
{
// image does not exist - we could choose to remove the image entirely here (return empty string),
// but that would leave the editors completely in the dark as to why the image doesn't show
return match.Value;
}
- var url = media.Url;
- return $"{match.Groups[1].Value}{url}{match.Groups[3].Value}{udi}{match.Groups[5].Value}";
+ return $"{match.Groups[1].Value}{mediaUrl}{match.Groups[3].Value}{udi}{match.Groups[5].Value}";
});
}
From bb2a3a5e3dc365b472a2e9f4a896bfd21b7256a3 Mon Sep 17 00:00:00 2001
From: Shannon
Date: Tue, 22 Oct 2019 11:09:21 +1100
Subject: [PATCH 07/15] stub class for udi parser
---
src/Umbraco.Web/Templates/MediaParser.cs | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/src/Umbraco.Web/Templates/MediaParser.cs b/src/Umbraco.Web/Templates/MediaParser.cs
index 4130b21da22b..2d20602e8e89 100644
--- a/src/Umbraco.Web/Templates/MediaParser.cs
+++ b/src/Umbraco.Web/Templates/MediaParser.cs
@@ -13,6 +13,22 @@
namespace Umbraco.Web.Templates
{
+ ///
+ /// Parses out UDIs in strings
+ ///
+ public sealed class UdiParser
+ {
+ ///
+ /// Parses out UDIs from an html string based on 'data-udi' html attributes
+ ///
+ ///
+ ///
+ public IEnumerable ParseUdisFromDataAttributes(string text)
+ {
+
+ }
+ }
+
public sealed class MediaParser
{
public MediaParser(IUmbracoContextAccessor umbracoContextAccessor, ILogger logger, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider)
From 6bb8a15a878346a9188577a2cca966df1e927bdf Mon Sep 17 00:00:00 2001
From: Shannon
Date: Tue, 22 Oct 2019 15:07:01 +1100
Subject: [PATCH 08/15] Adds UdiParserTests
---
.../{Web => Templates}/MediaParserTests.cs | 7 ++--
src/Umbraco.Tests/Templates/UdiParserTests.cs | 28 +++++++++++++++
src/Umbraco.Tests/Umbraco.Tests.csproj | 3 +-
src/Umbraco.Web/Templates/MediaParser.cs | 15 --------
src/Umbraco.Web/Templates/UdiParser.cs | 34 +++++++++++++++++++
src/Umbraco.Web/Umbraco.Web.csproj | 1 +
6 files changed, 69 insertions(+), 19 deletions(-)
rename src/Umbraco.Tests/{Web => Templates}/MediaParserTests.cs (98%)
create mode 100644 src/Umbraco.Tests/Templates/UdiParserTests.cs
create mode 100644 src/Umbraco.Web/Templates/UdiParser.cs
diff --git a/src/Umbraco.Tests/Web/MediaParserTests.cs b/src/Umbraco.Tests/Templates/MediaParserTests.cs
similarity index 98%
rename from src/Umbraco.Tests/Web/MediaParserTests.cs
rename to src/Umbraco.Tests/Templates/MediaParserTests.cs
index 7c9e7576b585..f7b5933a52c1 100644
--- a/src/Umbraco.Tests/Web/MediaParserTests.cs
+++ b/src/Umbraco.Tests/Templates/MediaParserTests.cs
@@ -13,8 +13,9 @@
using System.Linq;
using Umbraco.Core.Models;
-namespace Umbraco.Tests.Web
+namespace Umbraco.Tests.Templates
{
+
[TestFixture]
public class MediaParserTests
{
@@ -46,7 +47,7 @@ public void Remove_Image_Sources()
public void Ensure_Image_Sources()
{
//setup a mock url provider which we'll use for testing
-
+
var mediaType = new PublishedContentType(777, "image", PublishedItemType.Media, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
var media = new Mock();
media.Setup(x => x.ContentType).Returns(mediaType);
@@ -91,7 +92,7 @@ public void Ensure_Image_Sources()
}
-
+
}
}
}
diff --git a/src/Umbraco.Tests/Templates/UdiParserTests.cs b/src/Umbraco.Tests/Templates/UdiParserTests.cs
new file mode 100644
index 000000000000..eca7f6c4f02d
--- /dev/null
+++ b/src/Umbraco.Tests/Templates/UdiParserTests.cs
@@ -0,0 +1,28 @@
+using NUnit.Framework;
+using Umbraco.Web.Templates;
+using System.Linq;
+using Umbraco.Core;
+
+namespace Umbraco.Tests.Templates
+{
+ [TestFixture]
+ public class UdiParserTests
+ {
+ [Test]
+ public void Returns_Udi_From_Data_Udi_Html_Attributes()
+ {
+ var input = @"
+
+
+
+";
+
+ var parser = new UdiParser();
+ var result = parser.ParseUdisFromDataAttributes(input).ToList();
+ Assert.AreEqual(2, result.Count);
+ Assert.AreEqual(Udi.Parse("umb://media/D4B18427A1544721B09AC7692F35C264"), result[0]);
+ Assert.AreEqual(Udi.Parse("umb://media-type/B726D735E4C446D58F703F3FBCFC97A5"), result[1]);
+ }
+
+ }
+}
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index 20b29a31471d..519f36012c22 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -159,6 +159,7 @@
+
@@ -255,7 +256,7 @@
-
+
diff --git a/src/Umbraco.Web/Templates/MediaParser.cs b/src/Umbraco.Web/Templates/MediaParser.cs
index 2d20602e8e89..071c6a56966b 100644
--- a/src/Umbraco.Web/Templates/MediaParser.cs
+++ b/src/Umbraco.Web/Templates/MediaParser.cs
@@ -13,21 +13,6 @@
namespace Umbraco.Web.Templates
{
- ///
- /// Parses out UDIs in strings
- ///
- public sealed class UdiParser
- {
- ///
- /// Parses out UDIs from an html string based on 'data-udi' html attributes
- ///
- ///
- ///
- public IEnumerable ParseUdisFromDataAttributes(string text)
- {
-
- }
- }
public sealed class MediaParser
{
diff --git a/src/Umbraco.Web/Templates/UdiParser.cs b/src/Umbraco.Web/Templates/UdiParser.cs
new file mode 100644
index 000000000000..8bb5f8c57971
--- /dev/null
+++ b/src/Umbraco.Web/Templates/UdiParser.cs
@@ -0,0 +1,34 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using Umbraco.Core;
+
+namespace Umbraco.Web.Templates
+{
+ ///
+ /// Parses out UDIs in strings
+ ///
+ public sealed class UdiParser
+ {
+ private static readonly Regex DataUdiAttributeRegex = new Regex(@"data-udi=\\?(?:""|')(?umb://[A-z0-9\-]+/[A-z0-9]+)\\?(?:""|')",
+ RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
+
+ ///
+ /// Parses out UDIs from an html string based on 'data-udi' html attributes
+ ///
+ ///
+ ///
+ public IEnumerable ParseUdisFromDataAttributes(string text)
+ {
+ var matches = DataUdiAttributeRegex.Matches(text);
+ if (matches.Count == 0)
+ yield break;
+
+ foreach (Match match in matches)
+ {
+ if (match.Groups.Count == 2 && Udi.TryParse(match.Groups[1].Value, out var udi))
+ yield return udi;
+ }
+ }
+ }
+}
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 74ac3f65f397..276cdf9ebc02 100755
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -249,6 +249,7 @@
+
From 1adf5a30f361c4d9b779c28af35229c79db1e68c Mon Sep 17 00:00:00 2001
From: Shannon
Date: Tue, 22 Oct 2019 15:48:47 +1100
Subject: [PATCH 09/15] Renames some stuff, updates RTE editor to return
media/content refs and adds tests for locallink parsing
---
.../PublishedContentTestBase.cs | 2 +-
.../PublishedContent/PublishedContentTests.cs | 2 +-
...rserTests.cs => ImageSourceParserTests.cs} | 27 ++++++++-
.../Templates/LocalLinkParserTests.cs | 34 +++++++++++
src/Umbraco.Tests/Templates/UdiParserTests.cs | 28 ---------
src/Umbraco.Tests/Umbraco.Tests.csproj | 4 +-
.../Web/InternalLinkParserTests.cs | 2 +-
.../PropertyEditors/GridPropertyEditor.cs | 8 +--
.../PropertyEditors/RichTextPropertyEditor.cs | 12 ++--
.../MarkdownEditorValueConverter.cs | 4 +-
.../RteMacroRenderingValueConverter.cs | 6 +-
.../TextStringValueConverter.cs | 4 +-
src/Umbraco.Web/Runtime/WebInitialComposer.cs | 4 +-
.../{MediaParser.cs => ImageSourceParser.cs} | 27 ++++++++-
...ternalLinkParser.cs => LocalLinkParser.cs} | 58 +++++++++++++------
.../Templates/TemplateUtilities.cs | 8 +--
src/Umbraco.Web/Templates/UdiParser.cs | 34 -----------
src/Umbraco.Web/Umbraco.Web.csproj | 5 +-
src/Umbraco.Web/UmbracoComponentRenderer.cs | 4 +-
19 files changed, 156 insertions(+), 117 deletions(-)
rename src/Umbraco.Tests/Templates/{MediaParserTests.cs => ImageSourceParserTests.cs} (69%)
create mode 100644 src/Umbraco.Tests/Templates/LocalLinkParserTests.cs
delete mode 100644 src/Umbraco.Tests/Templates/UdiParserTests.cs
rename src/Umbraco.Web/Templates/{MediaParser.cs => ImageSourceParser.cs} (86%)
rename src/Umbraco.Web/Templates/{InternalLinkParser.cs => LocalLinkParser.cs} (63%)
delete mode 100644 src/Umbraco.Web/Templates/UdiParser.cs
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs
index 1fa3384d08e4..fec852f97abd 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs
@@ -43,7 +43,7 @@ protected override void Initialize()
var logger = Mock.Of();
var dataTypeService = new TestObjects.TestDataTypeService(
- new DataType(new RichTextPropertyEditor(logger, umbracoCtxAccessor, new MediaParser(umbracoCtxAccessor, logger, Mock.Of(), Mock.Of()))) { Id = 1 });
+ new DataType(new RichTextPropertyEditor(logger, umbracoCtxAccessor, new ImageSourceParser(umbracoCtxAccessor, logger, Mock.Of(), Mock.Of()))) { Id = 1 });
var publishedContentTypeFactory = new PublishedContentTypeFactory(Mock.Of(), converters, dataTypeService);
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
index d2f7283ee549..95d00998a15a 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
@@ -46,7 +46,7 @@ protected override void Compose()
var mediaService = Mock.Of();
var contentTypeBaseServiceProvider = Mock.Of();
var umbracoContextAccessor = Mock.Of();
- var mediaParser = new MediaParser(umbracoContextAccessor, logger, mediaService, contentTypeBaseServiceProvider);
+ var mediaParser = new ImageSourceParser(umbracoContextAccessor, logger, mediaService, contentTypeBaseServiceProvider);
var dataTypeService = new TestObjects.TestDataTypeService(
new DataType(new VoidEditor(logger)) { Id = 1 },
diff --git a/src/Umbraco.Tests/Templates/MediaParserTests.cs b/src/Umbraco.Tests/Templates/ImageSourceParserTests.cs
similarity index 69%
rename from src/Umbraco.Tests/Templates/MediaParserTests.cs
rename to src/Umbraco.Tests/Templates/ImageSourceParserTests.cs
index f7b5933a52c1..d383ab02dff3 100644
--- a/src/Umbraco.Tests/Templates/MediaParserTests.cs
+++ b/src/Umbraco.Tests/Templates/ImageSourceParserTests.cs
@@ -12,19 +12,40 @@
using System;
using System.Linq;
using Umbraco.Core.Models;
+using Umbraco.Core;
namespace Umbraco.Tests.Templates
{
+
[TestFixture]
- public class MediaParserTests
+ public class ImageSourceParserTests
{
+ [Test]
+ public void Returns_Udis_From_Data_Udi_Html_Attributes()
+ {
+ var input = @"
+
+
+
+";
+
+ var logger = Mock.Of();
+ var umbracoContextAccessor = new TestUmbracoContextAccessor();
+ var mediaParser = new ImageSourceParser(umbracoContextAccessor, logger, Mock.Of(), Mock.Of());
+
+ var result = mediaParser.FindUdisFromDataAttributes(input).ToList();
+ Assert.AreEqual(2, result.Count);
+ Assert.AreEqual(Udi.Parse("umb://media/D4B18427A1544721B09AC7692F35C264"), result[0]);
+ Assert.AreEqual(Udi.Parse("umb://media-type/B726D735E4C446D58F703F3FBCFC97A5"), result[1]);
+ }
+
[Test]
public void Remove_Image_Sources()
{
var logger = Mock.Of();
var umbracoContextAccessor = new TestUmbracoContextAccessor();
- var mediaParser = new MediaParser(umbracoContextAccessor, logger, Mock.Of(), Mock.Of());
+ var mediaParser = new ImageSourceParser(umbracoContextAccessor, logger, Mock.Of(), Mock.Of());
var result = mediaParser.RemoveImageSources(@"
@@ -66,7 +87,7 @@ public void Ensure_Image_Sources()
var mediaCache = Mock.Get(reference.UmbracoContext.Media);
mediaCache.Setup(x => x.GetById(It.IsAny
())).Returns(media.Object);
- var mediaParser = new MediaParser(umbracoContextAccessor, Mock.Of(), Mock.Of(), Mock.Of());
+ var mediaParser = new ImageSourceParser(umbracoContextAccessor, Mock.Of(), Mock.Of(), Mock.Of());
var result = mediaParser.EnsureImageSources(@"
diff --git a/src/Umbraco.Tests/Templates/LocalLinkParserTests.cs b/src/Umbraco.Tests/Templates/LocalLinkParserTests.cs
new file mode 100644
index 000000000000..30c79b311595
--- /dev/null
+++ b/src/Umbraco.Tests/Templates/LocalLinkParserTests.cs
@@ -0,0 +1,34 @@
+using NUnit.Framework;
+using System.Linq;
+using Umbraco.Core;
+using Umbraco.Tests.Testing.Objects.Accessors;
+using Umbraco.Web.Templates;
+
+namespace Umbraco.Tests.Templates
+{
+ [TestFixture]
+ public class LocalLinkParserTests
+ {
+ [Test]
+ public void Returns_Udis_From_LocalLinks()
+ {
+ var input = @"
+
+
+hello
+
";
+
+ var umbracoContextAccessor = new TestUmbracoContextAccessor();
+ var parser = new LocalLinkParser(umbracoContextAccessor);
+
+ var result = parser.FindUdisFromLocalLinks(input).ToList();
+
+ Assert.AreEqual(2, result.Count);
+ Assert.AreEqual(Udi.Parse("umb://document/C093961595094900AAF9170DDE6AD442"), result[0]);
+ Assert.AreEqual(Udi.Parse("umb://document-type/2D692FCB070B4CDA92FB6883FDBFD6E2"), result[1]);
+ }
+ }
+}
diff --git a/src/Umbraco.Tests/Templates/UdiParserTests.cs b/src/Umbraco.Tests/Templates/UdiParserTests.cs
deleted file mode 100644
index eca7f6c4f02d..000000000000
--- a/src/Umbraco.Tests/Templates/UdiParserTests.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using NUnit.Framework;
-using Umbraco.Web.Templates;
-using System.Linq;
-using Umbraco.Core;
-
-namespace Umbraco.Tests.Templates
-{
- [TestFixture]
- public class UdiParserTests
- {
- [Test]
- public void Returns_Udi_From_Data_Udi_Html_Attributes()
- {
- var input = @"
-
-
-
-
";
-
- var parser = new UdiParser();
- var result = parser.ParseUdisFromDataAttributes(input).ToList();
- Assert.AreEqual(2, result.Count);
- Assert.AreEqual(Udi.Parse("umb://media/D4B18427A1544721B09AC7692F35C264"), result[0]);
- Assert.AreEqual(Udi.Parse("umb://media-type/B726D735E4C446D58F703F3FBCFC97A5"), result[1]);
- }
-
- }
-}
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index 519f36012c22..d9583b939322 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -159,7 +159,7 @@
-
+
@@ -256,7 +256,7 @@
-
+
diff --git a/src/Umbraco.Tests/Web/InternalLinkParserTests.cs b/src/Umbraco.Tests/Web/InternalLinkParserTests.cs
index 0a948a861762..49da8d6566c6 100644
--- a/src/Umbraco.Tests/Web/InternalLinkParserTests.cs
+++ b/src/Umbraco.Tests/Web/InternalLinkParserTests.cs
@@ -65,7 +65,7 @@ public void ParseLocalLinks(string input, string result)
mediaCache.Setup(x => x.GetById(It.IsAny
())).Returns(media.Object);
mediaCache.Setup(x => x.GetById(It.IsAny())).Returns(media.Object);
- var linkParser = new InternalLinkParser(umbracoContextAccessor);
+ var linkParser = new LocalLinkParser(umbracoContextAccessor);
var output = linkParser.EnsureInternalLinks(input);
diff --git a/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs
index bec28e33fdfb..fa6346fdd86f 100644
--- a/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs
@@ -28,10 +28,10 @@ public class GridPropertyEditor : DataEditor
private IMediaService _mediaService;
private IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider;
private IUmbracoContextAccessor _umbracoContextAccessor;
- private readonly MediaParser _mediaParser;
+ private readonly ImageSourceParser _mediaParser;
private ILogger _logger;
- public GridPropertyEditor(ILogger logger, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor, MediaParser mediaParser)
+ public GridPropertyEditor(ILogger logger, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor, ImageSourceParser mediaParser)
: base(logger)
{
_mediaService = mediaService;
@@ -57,9 +57,9 @@ internal class GridPropertyValueEditor : DataValueEditor
private IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider;
private IUmbracoContextAccessor _umbracoContextAccessor;
private ILogger _logger;
- private readonly MediaParser _mediaParser;
+ private readonly ImageSourceParser _mediaParser;
- public GridPropertyValueEditor(DataEditorAttribute attribute, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor, ILogger logger, MediaParser _mediaParser)
+ public GridPropertyValueEditor(DataEditorAttribute attribute, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor, ILogger logger, ImageSourceParser _mediaParser)
: base(attribute)
{
_mediaService = mediaService;
diff --git a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs
index 03dc7b669425..4c7df4163c49 100644
--- a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
@@ -25,12 +26,13 @@ namespace Umbraco.Web.PropertyEditors
public class RichTextPropertyEditor : DataEditor
{
private IUmbracoContextAccessor _umbracoContextAccessor;
- private readonly MediaParser _mediaParser;
+ private readonly ImageSourceParser _mediaParser;
+
///
/// The constructor will setup the property editor based on the attribute if one is found
///
- public RichTextPropertyEditor(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor, MediaParser mediaParser)
+ public RichTextPropertyEditor(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor, ImageSourceParser mediaParser)
: base(logger)
{
_umbracoContextAccessor = umbracoContextAccessor;
@@ -53,9 +55,9 @@ public RichTextPropertyEditor(ILogger logger, IUmbracoContextAccessor umbracoCon
internal class RichTextPropertyValueEditor : DataValueEditor, IDataValueReference
{
private IUmbracoContextAccessor _umbracoContextAccessor;
- private readonly MediaParser _mediaParser;
+ private readonly ImageSourceParser _mediaParser;
- public RichTextPropertyValueEditor(DataEditorAttribute attribute, IUmbracoContextAccessor umbracoContextAccessor, MediaParser _mediaParser)
+ public RichTextPropertyValueEditor(DataEditorAttribute attribute, IUmbracoContextAccessor umbracoContextAccessor, ImageSourceParser _mediaParser)
: base(attribute)
{
_umbracoContextAccessor = umbracoContextAccessor;
@@ -127,7 +129,7 @@ public override object FromEditor(Core.Models.Editors.ContentPropertyData editor
///
public IEnumerable GetReferences(object value)
{
- throw new NotImplementedException();
+ return _mediaParser.FindUdisFromDataAttributes(value == null ? string.Empty : value is string str ? str : value.ToString()).ToList();
}
}
diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs
index 578a4cad065f..e8a2ac11a63e 100644
--- a/src/Umbraco.Web/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs
+++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs
@@ -12,10 +12,10 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
[DefaultPropertyValueConverter]
public class MarkdownEditorValueConverter : PropertyValueConverterBase
{
- private readonly InternalLinkParser _localLinkParser;
+ private readonly LocalLinkParser _localLinkParser;
private readonly UrlParser _urlResolver;
- public MarkdownEditorValueConverter(InternalLinkParser localLinkParser, UrlParser urlResolver)
+ public MarkdownEditorValueConverter(LocalLinkParser localLinkParser, UrlParser urlResolver)
{
_localLinkParser = localLinkParser;
_urlResolver = urlResolver;
diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs
index 88c1429b1600..2caac9e1f483 100644
--- a/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs
+++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs
@@ -24,9 +24,9 @@ public class RteMacroRenderingValueConverter : TinyMceValueConverter
{
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
private readonly IMacroRenderer _macroRenderer;
- private readonly InternalLinkParser _internalLinkParser;
+ private readonly LocalLinkParser _internalLinkParser;
private readonly UrlParser _urlResolver;
- private readonly MediaParser _mediaParser;
+ private readonly ImageSourceParser _mediaParser;
public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType)
{
@@ -36,7 +36,7 @@ public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType
}
public RteMacroRenderingValueConverter(IUmbracoContextAccessor umbracoContextAccessor, IMacroRenderer macroRenderer,
- InternalLinkParser internalLinkParser, UrlParser urlResolver, MediaParser mediaParser)
+ LocalLinkParser internalLinkParser, UrlParser urlResolver, ImageSourceParser mediaParser)
{
_umbracoContextAccessor = umbracoContextAccessor;
_macroRenderer = macroRenderer;
diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/TextStringValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/TextStringValueConverter.cs
index 1b85d6e608de..5efc2ee2db07 100644
--- a/src/Umbraco.Web/PropertyEditors/ValueConverters/TextStringValueConverter.cs
+++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/TextStringValueConverter.cs
@@ -11,7 +11,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
[DefaultPropertyValueConverter]
public class TextStringValueConverter : PropertyValueConverterBase
{
- public TextStringValueConverter(InternalLinkParser internalLinkParser, UrlParser urlParser)
+ public TextStringValueConverter(LocalLinkParser internalLinkParser, UrlParser urlParser)
{
_internalLinkParser = internalLinkParser;
_urlParser = urlParser;
@@ -22,7 +22,7 @@ public TextStringValueConverter(InternalLinkParser internalLinkParser, UrlParser
Constants.PropertyEditors.Aliases.TextBox,
Constants.PropertyEditors.Aliases.TextArea
};
- private readonly InternalLinkParser _internalLinkParser;
+ private readonly LocalLinkParser _internalLinkParser;
private readonly UrlParser _urlParser;
public override bool IsConverter(IPublishedPropertyType propertyType)
diff --git a/src/Umbraco.Web/Runtime/WebInitialComposer.cs b/src/Umbraco.Web/Runtime/WebInitialComposer.cs
index 1b3128388dcf..2f78ac97329b 100644
--- a/src/Umbraco.Web/Runtime/WebInitialComposer.cs
+++ b/src/Umbraco.Web/Runtime/WebInitialComposer.cs
@@ -107,9 +107,9 @@ public override void Compose(Composition composition)
composition.RegisterUnique();
composition.RegisterUnique();
- composition.RegisterUnique();
+ composition.RegisterUnique();
composition.RegisterUnique();
- composition.RegisterUnique();
+ composition.RegisterUnique();
// register the umbraco helper - this is Transient! very important!
// also, if not level.Run, we cannot really use the helper (during upgrade...)
diff --git a/src/Umbraco.Web/Templates/MediaParser.cs b/src/Umbraco.Web/Templates/ImageSourceParser.cs
similarity index 86%
rename from src/Umbraco.Web/Templates/MediaParser.cs
rename to src/Umbraco.Web/Templates/ImageSourceParser.cs
index 071c6a56966b..6a0bba499844 100644
--- a/src/Umbraco.Web/Templates/MediaParser.cs
+++ b/src/Umbraco.Web/Templates/ImageSourceParser.cs
@@ -14,9 +14,9 @@
namespace Umbraco.Web.Templates
{
- public sealed class MediaParser
+ public sealed class ImageSourceParser
{
- public MediaParser(IUmbracoContextAccessor umbracoContextAccessor, ILogger logger, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider)
+ public ImageSourceParser(IUmbracoContextAccessor umbracoContextAccessor, ILogger logger, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider)
{
_umbracoContextAccessor = umbracoContextAccessor;
_logger = logger;
@@ -32,6 +32,27 @@ public MediaParser(IUmbracoContextAccessor umbracoContextAccessor, ILogger logge
private readonly IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider;
const string TemporaryImageDataAttribute = "data-tmpimg";
+ private static readonly Regex DataUdiAttributeRegex = new Regex(@"data-udi=\\?(?:""|')(?umb://[A-z0-9\-]+/[A-z0-9]+)\\?(?:""|')",
+ RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
+
+ ///
+ /// Parses out UDIs from an html string based on 'data-udi' html attributes
+ ///
+ ///
+ ///
+ public IEnumerable FindUdisFromDataAttributes(string text)
+ {
+ var matches = DataUdiAttributeRegex.Matches(text);
+ if (matches.Count == 0)
+ yield break;
+
+ foreach (Match match in matches)
+ {
+ if (match.Groups.Count == 2 && Udi.TryParse(match.Groups[1].Value, out var udi))
+ yield return udi;
+ }
+ }
+
///
/// Parses the string looking for Umbraco image tags and updates them to their up-to-date image sources.
///
@@ -178,7 +199,7 @@ internal string FindAndPersistPastedTempImages(string html, Guid mediaParentFold
}
catch (Exception ex)
{
- _logger.Error(typeof(MediaParser), ex, "Could not delete temp file or folder {FileName}", absoluteTempImagePath);
+ _logger.Error(typeof(ImageSourceParser), ex, "Could not delete temp file or folder {FileName}", absoluteTempImagePath);
}
}
}
diff --git a/src/Umbraco.Web/Templates/InternalLinkParser.cs b/src/Umbraco.Web/Templates/LocalLinkParser.cs
similarity index 63%
rename from src/Umbraco.Web/Templates/InternalLinkParser.cs
rename to src/Umbraco.Web/Templates/LocalLinkParser.cs
index 32d7d42eac3f..f394f56d854e 100644
--- a/src/Umbraco.Web/Templates/InternalLinkParser.cs
+++ b/src/Umbraco.Web/Templates/LocalLinkParser.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Text.RegularExpressions;
using Umbraco.Core;
using Umbraco.Core.Logging;
@@ -10,7 +11,7 @@ namespace Umbraco.Web.Templates
///
/// Utility class used to parse internal links
///
- public sealed class InternalLinkParser
+ public sealed class LocalLinkParser
{
private static readonly Regex LocalLinkPattern = new Regex(@"href=""[/]?(?:\{|\%7B)localLink:([a-zA-Z0-9-://]+)(?:\}|\%7D)",
@@ -18,11 +19,20 @@ public sealed class InternalLinkParser
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
- public InternalLinkParser(IUmbracoContextAccessor umbracoContextAccessor)
+ public LocalLinkParser(IUmbracoContextAccessor umbracoContextAccessor)
{
_umbracoContextAccessor = umbracoContextAccessor;
}
+ internal IEnumerable FindUdisFromLocalLinks(string text)
+ {
+ foreach ((int? intId, GuidUdi udi, string tagValue) in FindLocalLinkIds(text))
+ {
+ if (udi != null)
+ yield return udi; // In v8, we only care abuot UDIs
+ }
+ }
+
///
/// Parses the string looking for the {localLink} syntax and updates them to their correct links.
///
@@ -56,6 +66,33 @@ public string EnsureInternalLinks(string text)
var urlProvider = _umbracoContextAccessor.UmbracoContext.UrlProvider;
+ foreach((int? intId, GuidUdi udi, string tagValue) in FindLocalLinkIds(text))
+ {
+ if (udi != null)
+ {
+ var newLink = "#";
+ if (udi.EntityType == Constants.UdiEntityType.Document)
+ newLink = urlProvider.GetUrl(udi.Guid);
+ else if (udi.EntityType == Constants.UdiEntityType.Media)
+ newLink = urlProvider.GetMediaUrl(udi.Guid);
+
+ if (newLink == null)
+ newLink = "#";
+
+ text = text.Replace(tagValue, "href=\"" + newLink);
+ }
+ else if (intId.HasValue)
+ {
+ var newLink = urlProvider.GetUrl(intId.Value);
+ text = text.Replace(tagValue, "href=\"" + newLink);
+ }
+ }
+
+ return text;
+ }
+
+ private IEnumerable<(int? intId, GuidUdi udi, string tagValue)> FindLocalLinkIds(string text)
+ {
// Parse internal links
var tags = LocalLinkPattern.Matches(text);
foreach (Match tag in tags)
@@ -69,29 +106,16 @@ public string EnsureInternalLinks(string text)
{
var guidUdi = udi as GuidUdi;
if (guidUdi != null)
- {
- var newLink = "#";
- if (guidUdi.EntityType == Constants.UdiEntityType.Document)
- newLink = urlProvider.GetUrl(guidUdi.Guid);
- else if (guidUdi.EntityType == Constants.UdiEntityType.Media)
- newLink = urlProvider.GetMediaUrl(guidUdi.Guid);
-
- if (newLink == null)
- newLink = "#";
-
- text = text.Replace(tag.Value, "href=\"" + newLink);
- }
+ yield return (null, guidUdi, tag.Value);
}
if (int.TryParse(id, out var intId))
{
- var newLink = urlProvider.GetUrl(intId);
- text = text.Replace(tag.Value, "href=\"" + newLink);
+ yield return (intId, null, tag.Value);
}
}
}
- return text;
}
}
}
diff --git a/src/Umbraco.Web/Templates/TemplateUtilities.cs b/src/Umbraco.Web/Templates/TemplateUtilities.cs
index d4bae3814726..db0366dbf3d5 100644
--- a/src/Umbraco.Web/Templates/TemplateUtilities.cs
+++ b/src/Umbraco.Web/Templates/TemplateUtilities.cs
@@ -31,7 +31,7 @@ internal static string ParseInternalLinks(string text, bool preview, UmbracoCont
[Obsolete("Inject and use an instance of InternalLinkParser instead")]
public static string ParseInternalLinks(string text, UrlProvider urlProvider)
- => Current.Factory.GetInstance().EnsureInternalLinks(text);
+ => Current.Factory.GetInstance().EnsureInternalLinks(text);
[Obsolete("Inject and use an instance of UrlResolver")]
public static string ResolveUrlsFromTextString(string text)
@@ -43,14 +43,14 @@ public static string CleanForXss(string text, params char[] ignoreFromClean)
[Obsolete("Use MediaParser.EnsureImageSources instead")]
public static string ResolveMediaFromTextString(string text)
- => Current.Factory.GetInstance().EnsureImageSources(text);
+ => Current.Factory.GetInstance().EnsureImageSources(text);
[Obsolete("Use MediaParser.RemoveImageSources instead")]
internal static string RemoveMediaUrlsFromTextString(string text)
- => Current.Factory.GetInstance().RemoveImageSources(text);
+ => Current.Factory.GetInstance().RemoveImageSources(text);
[Obsolete("Use MediaParser.RemoveImageSources instead")]
internal static string FindAndPersistPastedTempImages(string html, Guid mediaParentFolder, int userId, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, ILogger logger)
- => Current.Factory.GetInstance().FindAndPersistPastedTempImages(html, mediaParentFolder, userId);
+ => Current.Factory.GetInstance().FindAndPersistPastedTempImages(html, mediaParentFolder, userId);
}
}
diff --git a/src/Umbraco.Web/Templates/UdiParser.cs b/src/Umbraco.Web/Templates/UdiParser.cs
deleted file mode 100644
index 8bb5f8c57971..000000000000
--- a/src/Umbraco.Web/Templates/UdiParser.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Text.RegularExpressions;
-using Umbraco.Core;
-
-namespace Umbraco.Web.Templates
-{
- ///
- /// Parses out UDIs in strings
- ///
- public sealed class UdiParser
- {
- private static readonly Regex DataUdiAttributeRegex = new Regex(@"data-udi=\\?(?:""|')(?umb://[A-z0-9\-]+/[A-z0-9]+)\\?(?:""|')",
- RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
-
- ///
- /// Parses out UDIs from an html string based on 'data-udi' html attributes
- ///
- ///
- ///
- public IEnumerable ParseUdisFromDataAttributes(string text)
- {
- var matches = DataUdiAttributeRegex.Matches(text);
- if (matches.Count == 0)
- yield break;
-
- foreach (Match match in matches)
- {
- if (match.Groups.Count == 2 && Udi.TryParse(match.Groups[1].Value, out var udi))
- yield return udi;
- }
- }
- }
-}
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 276cdf9ebc02..8fc06c75c273 100755
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -247,9 +247,8 @@
-
-
-
+
+
diff --git a/src/Umbraco.Web/UmbracoComponentRenderer.cs b/src/Umbraco.Web/UmbracoComponentRenderer.cs
index c0f83fd1af3e..83c8a7f0faa1 100644
--- a/src/Umbraco.Web/UmbracoComponentRenderer.cs
+++ b/src/Umbraco.Web/UmbracoComponentRenderer.cs
@@ -27,9 +27,9 @@ internal class UmbracoComponentRenderer : IUmbracoComponentRenderer
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
private readonly IMacroRenderer _macroRenderer;
private readonly ITemplateRenderer _templateRenderer;
- private readonly InternalLinkParser _internalLinkParser;
+ private readonly LocalLinkParser _internalLinkParser;
- public UmbracoComponentRenderer(IUmbracoContextAccessor umbracoContextAccessor, IMacroRenderer macroRenderer, ITemplateRenderer templateRenderer, InternalLinkParser internalLinkParser)
+ public UmbracoComponentRenderer(IUmbracoContextAccessor umbracoContextAccessor, IMacroRenderer macroRenderer, ITemplateRenderer templateRenderer, LocalLinkParser internalLinkParser)
{
_umbracoContextAccessor = umbracoContextAccessor;
_macroRenderer = macroRenderer;
From aee3b9f9d28b810e893cfd73ad4c0c35504f5371 Mon Sep 17 00:00:00 2001
From: Shannon
Date: Tue, 22 Oct 2019 15:52:09 +1100
Subject: [PATCH 10/15] updates rte editor to return local link udis
---
.../PropertyEditors/RichTextPropertyEditor.cs | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs
index 4c7df4163c49..8cb9536182e1 100644
--- a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs
@@ -56,12 +56,14 @@ internal class RichTextPropertyValueEditor : DataValueEditor, IDataValueReferenc
{
private IUmbracoContextAccessor _umbracoContextAccessor;
private readonly ImageSourceParser _mediaParser;
+ private readonly LocalLinkParser _localLinkParser;
- public RichTextPropertyValueEditor(DataEditorAttribute attribute, IUmbracoContextAccessor umbracoContextAccessor, ImageSourceParser _mediaParser)
+ public RichTextPropertyValueEditor(DataEditorAttribute attribute, IUmbracoContextAccessor umbracoContextAccessor, ImageSourceParser mediaParser, LocalLinkParser localLinkParser)
: base(attribute)
{
_umbracoContextAccessor = umbracoContextAccessor;
- this._mediaParser = _mediaParser;
+ _mediaParser = mediaParser;
+ _localLinkParser = localLinkParser;
}
///
@@ -129,7 +131,15 @@ public override object FromEditor(Core.Models.Editors.ContentPropertyData editor
///
public IEnumerable GetReferences(object value)
{
- return _mediaParser.FindUdisFromDataAttributes(value == null ? string.Empty : value is string str ? str : value.ToString()).ToList();
+ var asString = value == null ? string.Empty : value is string str ? str : value.ToString();
+
+ foreach (var udi in _mediaParser.FindUdisFromDataAttributes(asString))
+ yield return udi;
+
+ foreach (var udi in _localLinkParser.FindUdisFromLocalLinks(asString))
+ yield return udi;
+
+ //TODO: Detect Macros too ... but we can save that for a later date, right now need to do media refs
}
}
From 611ba7de46e9aa4c113ae6e1c081a7a994b594f7 Mon Sep 17 00:00:00 2001
From: Shannon
Date: Tue, 22 Oct 2019 16:12:31 +1100
Subject: [PATCH 11/15] fix build
---
src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs
index 8cb9536182e1..2b3e7499534e 100644
--- a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs
@@ -27,23 +27,25 @@ public class RichTextPropertyEditor : DataEditor
{
private IUmbracoContextAccessor _umbracoContextAccessor;
private readonly ImageSourceParser _mediaParser;
-
+ private readonly LocalLinkParser _localLinkParser;
+
///
/// The constructor will setup the property editor based on the attribute if one is found
///
- public RichTextPropertyEditor(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor, ImageSourceParser mediaParser)
+ public RichTextPropertyEditor(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor, ImageSourceParser mediaParser, LocalLinkParser localLinkParser)
: base(logger)
{
_umbracoContextAccessor = umbracoContextAccessor;
_mediaParser = mediaParser;
+ _localLinkParser = localLinkParser;
}
///
/// Create a custom value editor
///
///
- protected override IDataValueEditor CreateValueEditor() => new RichTextPropertyValueEditor(Attribute, _umbracoContextAccessor, _mediaParser);
+ protected override IDataValueEditor CreateValueEditor() => new RichTextPropertyValueEditor(Attribute, _umbracoContextAccessor, _mediaParser, _localLinkParser);
protected override IConfigurationEditor CreateConfigurationEditor() => new RichTextConfigurationEditor();
From 832803a9f64d7ab3a8f6dbb2b94f59f75f7f3318 Mon Sep 17 00:00:00 2001
From: Shannon
Date: Wed, 23 Oct 2019 14:35:43 +1100
Subject: [PATCH 12/15] fix build
---
.../PublishedContent/PublishedContentTestBase.cs | 6 ++++--
src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs | 3 ++-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs
index fec852f97abd..6c68fecdd290 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs
@@ -39,11 +39,13 @@ protected override void Initialize()
base.Initialize();
var converters = Factory.GetInstance();
- var umbracoCtxAccessor = Mock.Of();
+ var umbracoContextAccessor = Mock.Of();
var logger = Mock.Of();
+ var imageSourceParser = new ImageSourceParser(umbracoContextAccessor, logger, Mock.Of(), Mock.Of());
+ var localLinkParser = new LocalLinkParser(umbracoContextAccessor);
var dataTypeService = new TestObjects.TestDataTypeService(
- new DataType(new RichTextPropertyEditor(logger, umbracoCtxAccessor, new ImageSourceParser(umbracoCtxAccessor, logger, Mock.Of(), Mock.Of()))) { Id = 1 });
+ new DataType(new RichTextPropertyEditor(logger, umbracoContextAccessor, imageSourceParser, localLinkParser)) { Id = 1 });
var publishedContentTypeFactory = new PublishedContentTypeFactory(Mock.Of(), converters, dataTypeService);
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
index 95d00998a15a..333f3ca7c04c 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
@@ -47,11 +47,12 @@ protected override void Compose()
var contentTypeBaseServiceProvider = Mock.Of();
var umbracoContextAccessor = Mock.Of();
var mediaParser = new ImageSourceParser(umbracoContextAccessor, logger, mediaService, contentTypeBaseServiceProvider);
+ var localLinkParser = new LocalLinkParser(umbracoContextAccessor);
var dataTypeService = new TestObjects.TestDataTypeService(
new DataType(new VoidEditor(logger)) { Id = 1 },
new DataType(new TrueFalsePropertyEditor(logger)) { Id = 1001 },
- new DataType(new RichTextPropertyEditor(logger, umbracoContextAccessor, mediaParser)) { Id = 1002 },
+ new DataType(new RichTextPropertyEditor(logger, umbracoContextAccessor, mediaParser, localLinkParser)) { Id = 1002 },
new DataType(new IntegerPropertyEditor(logger)) { Id = 1003 },
new DataType(new TextboxPropertyEditor(logger)) { Id = 1004 },
new DataType(new MediaPickerPropertyEditor(logger)) { Id = 1005 });
From 17fd09fe3df0576dc6823cf3fa8d2d9d695a0912 Mon Sep 17 00:00:00 2001
From: Shannon
Date: Wed, 23 Oct 2019 14:55:18 +1100
Subject: [PATCH 13/15] Naming
---
.../PublishedContentTestBase.cs | 4 +--
.../PublishedContent/PublishedContentTests.cs | 6 ++--
.../Templates/ImageSourceParserTests.cs | 12 +++----
.../Templates/LocalLinkParserTests.cs | 2 +-
src/Umbraco.Tests/Umbraco.Tests.csproj | 2 +-
...erTests.cs => HtmlLocalLinkParserTests.cs} | 4 +--
.../PropertyEditors/GridPropertyEditor.cs | 32 ++++++-------------
.../PropertyEditors/RichTextPropertyEditor.cs | 26 +++++++--------
.../MarkdownEditorValueConverter.cs | 10 +++---
.../RteMacroRenderingValueConverter.cs | 20 ++++++------
.../TextStringValueConverter.cs | 10 +++---
src/Umbraco.Web/Runtime/WebInitialComposer.cs | 6 ++--
...urceParser.cs => HtmlImageSourceParser.cs} | 15 ++++++---
...alLinkParser.cs => HtmlLocalLinkParser.cs} | 4 +--
.../{UrlParser.cs => HtmlUrlParser.cs} | 4 +--
.../Templates/TemplateUtilities.cs | 24 +++++++-------
src/Umbraco.Web/Umbraco.Web.csproj | 6 ++--
src/Umbraco.Web/UmbracoComponentRenderer.cs | 8 ++---
18 files changed, 95 insertions(+), 100 deletions(-)
rename src/Umbraco.Tests/Web/{InternalLinkParserTests.cs => HtmlLocalLinkParserTests.cs} (97%)
rename src/Umbraco.Web/Templates/{ImageSourceParser.cs => HtmlImageSourceParser.cs} (92%)
rename src/Umbraco.Web/Templates/{LocalLinkParser.cs => HtmlLocalLinkParser.cs} (97%)
rename src/Umbraco.Web/Templates/{UrlParser.cs => HtmlUrlParser.cs} (95%)
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs
index 6c68fecdd290..497c62196363 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs
@@ -42,8 +42,8 @@ protected override void Initialize()
var umbracoContextAccessor = Mock.Of();
var logger = Mock.Of();
- var imageSourceParser = new ImageSourceParser(umbracoContextAccessor, logger, Mock.Of(), Mock.Of());
- var localLinkParser = new LocalLinkParser(umbracoContextAccessor);
+ var imageSourceParser = new HtmlImageSourceParser(umbracoContextAccessor, logger, Mock.Of(), Mock.Of());
+ var localLinkParser = new HtmlLocalLinkParser(umbracoContextAccessor);
var dataTypeService = new TestObjects.TestDataTypeService(
new DataType(new RichTextPropertyEditor(logger, umbracoContextAccessor, imageSourceParser, localLinkParser)) { Id = 1 });
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
index 333f3ca7c04c..9f5dc8198641 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
@@ -46,13 +46,13 @@ protected override void Compose()
var mediaService = Mock.Of();
var contentTypeBaseServiceProvider = Mock.Of();
var umbracoContextAccessor = Mock.Of();
- var mediaParser = new ImageSourceParser(umbracoContextAccessor, logger, mediaService, contentTypeBaseServiceProvider);
- var localLinkParser = new LocalLinkParser(umbracoContextAccessor);
+ var imageSourceParser = new HtmlImageSourceParser(umbracoContextAccessor, logger, mediaService, contentTypeBaseServiceProvider);
+ var linkParser = new HtmlLocalLinkParser(umbracoContextAccessor);
var dataTypeService = new TestObjects.TestDataTypeService(
new DataType(new VoidEditor(logger)) { Id = 1 },
new DataType(new TrueFalsePropertyEditor(logger)) { Id = 1001 },
- new DataType(new RichTextPropertyEditor(logger, umbracoContextAccessor, mediaParser, localLinkParser)) { Id = 1002 },
+ new DataType(new RichTextPropertyEditor(logger, umbracoContextAccessor, imageSourceParser, linkParser)) { Id = 1002 },
new DataType(new IntegerPropertyEditor(logger)) { Id = 1003 },
new DataType(new TextboxPropertyEditor(logger)) { Id = 1004 },
new DataType(new MediaPickerPropertyEditor(logger)) { Id = 1005 });
diff --git a/src/Umbraco.Tests/Templates/ImageSourceParserTests.cs b/src/Umbraco.Tests/Templates/ImageSourceParserTests.cs
index d383ab02dff3..ca01caf34481 100644
--- a/src/Umbraco.Tests/Templates/ImageSourceParserTests.cs
+++ b/src/Umbraco.Tests/Templates/ImageSourceParserTests.cs
@@ -32,9 +32,9 @@ public void Returns_Udis_From_Data_Udi_Html_Attributes()
var logger = Mock.Of();
var umbracoContextAccessor = new TestUmbracoContextAccessor();
- var mediaParser = new ImageSourceParser(umbracoContextAccessor, logger, Mock.Of(), Mock.Of());
+ var imageSourceParser = new HtmlImageSourceParser(umbracoContextAccessor, logger, Mock.Of(), Mock.Of());
- var result = mediaParser.FindUdisFromDataAttributes(input).ToList();
+ var result = imageSourceParser.FindUdisFromDataAttributes(input).ToList();
Assert.AreEqual(2, result.Count);
Assert.AreEqual(Udi.Parse("umb://media/D4B18427A1544721B09AC7692F35C264"), result[0]);
Assert.AreEqual(Udi.Parse("umb://media-type/B726D735E4C446D58F703F3FBCFC97A5"), result[1]);
@@ -45,9 +45,9 @@ public void Remove_Image_Sources()
{
var logger = Mock.Of();
var umbracoContextAccessor = new TestUmbracoContextAccessor();
- var mediaParser = new ImageSourceParser(umbracoContextAccessor, logger, Mock.Of(), Mock.Of());
+ var imageSourceParser = new HtmlImageSourceParser(umbracoContextAccessor, logger, Mock.Of(), Mock.Of());
- var result = mediaParser.RemoveImageSources(@"
+ var result = imageSourceParser.RemoveImageSources(@"
@@ -87,9 +87,9 @@ public void Ensure_Image_Sources()
var mediaCache = Mock.Get(reference.UmbracoContext.Media);
mediaCache.Setup(x => x.GetById(It.IsAny())).Returns(media.Object);
- var mediaParser = new ImageSourceParser(umbracoContextAccessor, Mock.Of(), Mock.Of(), Mock.Of());
+ var imageSourceParser = new HtmlImageSourceParser(umbracoContextAccessor, Mock.Of(), Mock.Of(), Mock.Of());
- var result = mediaParser.EnsureImageSources(@"
+ var result = imageSourceParser.EnsureImageSources(@"
diff --git a/src/Umbraco.Tests/Templates/LocalLinkParserTests.cs b/src/Umbraco.Tests/Templates/LocalLinkParserTests.cs
index 30c79b311595..e09d71196ebc 100644
--- a/src/Umbraco.Tests/Templates/LocalLinkParserTests.cs
+++ b/src/Umbraco.Tests/Templates/LocalLinkParserTests.cs
@@ -22,7 +22,7 @@ public void Returns_Udis_From_LocalLinks()
";
var umbracoContextAccessor = new TestUmbracoContextAccessor();
- var parser = new LocalLinkParser(umbracoContextAccessor);
+ var parser = new HtmlLocalLinkParser(umbracoContextAccessor);
var result = parser.FindUdisFromLocalLinks(input).ToList();
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index d9583b939322..fa654ad4a49d 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -255,7 +255,7 @@
-
+
diff --git a/src/Umbraco.Tests/Web/InternalLinkParserTests.cs b/src/Umbraco.Tests/Web/HtmlLocalLinkParserTests.cs
similarity index 97%
rename from src/Umbraco.Tests/Web/InternalLinkParserTests.cs
rename to src/Umbraco.Tests/Web/HtmlLocalLinkParserTests.cs
index 49da8d6566c6..e6a0abeb4c4d 100644
--- a/src/Umbraco.Tests/Web/InternalLinkParserTests.cs
+++ b/src/Umbraco.Tests/Web/HtmlLocalLinkParserTests.cs
@@ -19,7 +19,7 @@ namespace Umbraco.Tests.Web
{
[TestFixture]
- public class InternalLinkParserTests
+ public class HtmlLocalLinkParserTests
{
[TestCase("", "")]
[TestCase("hello href=\"{localLink:1234}\" world ", "hello href=\"/my-test-url\" world ")]
@@ -65,7 +65,7 @@ public void ParseLocalLinks(string input, string result)
mediaCache.Setup(x => x.GetById(It.IsAny())).Returns(media.Object);
mediaCache.Setup(x => x.GetById(It.IsAny())).Returns(media.Object);
- var linkParser = new LocalLinkParser(umbracoContextAccessor);
+ var linkParser = new HtmlLocalLinkParser(umbracoContextAccessor);
var output = linkParser.EnsureInternalLinks(input);
diff --git a/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs
index fa6346fdd86f..6481099f45e5 100644
--- a/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs
@@ -25,20 +25,14 @@ namespace Umbraco.Web.PropertyEditors
Group = Constants.PropertyEditors.Groups.RichContent)]
public class GridPropertyEditor : DataEditor
{
- private IMediaService _mediaService;
- private IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider;
private IUmbracoContextAccessor _umbracoContextAccessor;
- private readonly ImageSourceParser _mediaParser;
- private ILogger _logger;
+ private readonly HtmlImageSourceParser _imageSourceParser;
- public GridPropertyEditor(ILogger logger, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor, ImageSourceParser mediaParser)
+ public GridPropertyEditor(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor, HtmlImageSourceParser imageSourceParser)
: base(logger)
{
- _mediaService = mediaService;
- _contentTypeBaseServiceProvider = contentTypeBaseServiceProvider;
_umbracoContextAccessor = umbracoContextAccessor;
- _mediaParser = mediaParser;
- _logger = logger;
+ _imageSourceParser = imageSourceParser;
}
public override IPropertyIndexValueFactory PropertyIndexValueFactory => new GridPropertyIndexValueFactory();
@@ -47,26 +41,20 @@ public GridPropertyEditor(ILogger logger, IMediaService mediaService, IContentTy
/// Overridden to ensure that the value is validated
///
///
- protected override IDataValueEditor CreateValueEditor() => new GridPropertyValueEditor(Attribute, _mediaService, _contentTypeBaseServiceProvider, _umbracoContextAccessor, _logger, _mediaParser);
+ protected override IDataValueEditor CreateValueEditor() => new GridPropertyValueEditor(Attribute, _umbracoContextAccessor, _imageSourceParser);
protected override IConfigurationEditor CreateConfigurationEditor() => new GridConfigurationEditor();
internal class GridPropertyValueEditor : DataValueEditor
{
- private IMediaService _mediaService;
- private IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider;
private IUmbracoContextAccessor _umbracoContextAccessor;
- private ILogger _logger;
- private readonly ImageSourceParser _mediaParser;
+ private readonly HtmlImageSourceParser _imageSourceParser;
- public GridPropertyValueEditor(DataEditorAttribute attribute, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor, ILogger logger, ImageSourceParser _mediaParser)
+ public GridPropertyValueEditor(DataEditorAttribute attribute, IUmbracoContextAccessor umbracoContextAccessor, HtmlImageSourceParser imageSourceParser)
: base(attribute)
{
- _mediaService = mediaService;
- _contentTypeBaseServiceProvider = contentTypeBaseServiceProvider;
_umbracoContextAccessor = umbracoContextAccessor;
- _logger = logger;
- this._mediaParser = _mediaParser;
+ _imageSourceParser = imageSourceParser;
}
///
@@ -101,8 +89,8 @@ public override object FromEditor(ContentPropertyData editorValue, object curren
// Parse the HTML
var html = rte.Value?.ToString();
- var parseAndSavedTempImages = _mediaParser.FindAndPersistPastedTempImages(html, mediaParentId, userId);
- var editorValueWithMediaUrlsRemoved = _mediaParser.RemoveImageSources(parseAndSavedTempImages);
+ var parseAndSavedTempImages = _imageSourceParser.FindAndPersistPastedTempImages(html, mediaParentId, userId);
+ var editorValueWithMediaUrlsRemoved = _imageSourceParser.RemoveImageSources(parseAndSavedTempImages);
rte.Value = editorValueWithMediaUrlsRemoved;
}
@@ -131,7 +119,7 @@ public override object ToEditor(Property property, IDataTypeService dataTypeServ
{
var html = rte.Value?.ToString();
- var propertyValueWithMediaResolved = _mediaParser.EnsureImageSources(html);
+ var propertyValueWithMediaResolved = _imageSourceParser.EnsureImageSources(html);
rte.Value = propertyValueWithMediaResolved;
}
diff --git a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs
index 2b3e7499534e..0dbe5426a29a 100644
--- a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs
@@ -26,18 +26,18 @@ namespace Umbraco.Web.PropertyEditors
public class RichTextPropertyEditor : DataEditor
{
private IUmbracoContextAccessor _umbracoContextAccessor;
- private readonly ImageSourceParser _mediaParser;
- private readonly LocalLinkParser _localLinkParser;
+ private readonly HtmlImageSourceParser _imageSourceParser;
+ private readonly HtmlLocalLinkParser _localLinkParser;
///
/// The constructor will setup the property editor based on the attribute if one is found
///
- public RichTextPropertyEditor(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor, ImageSourceParser mediaParser, LocalLinkParser localLinkParser)
+ public RichTextPropertyEditor(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor, HtmlImageSourceParser imageSourceParser, HtmlLocalLinkParser localLinkParser)
: base(logger)
{
_umbracoContextAccessor = umbracoContextAccessor;
- _mediaParser = mediaParser;
+ _imageSourceParser = imageSourceParser;
_localLinkParser = localLinkParser;
}
@@ -45,7 +45,7 @@ public RichTextPropertyEditor(ILogger logger, IUmbracoContextAccessor umbracoCon
/// Create a custom value editor
///
///
- protected override IDataValueEditor CreateValueEditor() => new RichTextPropertyValueEditor(Attribute, _umbracoContextAccessor, _mediaParser, _localLinkParser);
+ protected override IDataValueEditor CreateValueEditor() => new RichTextPropertyValueEditor(Attribute, _umbracoContextAccessor, _imageSourceParser, _localLinkParser);
protected override IConfigurationEditor CreateConfigurationEditor() => new RichTextConfigurationEditor();
@@ -57,14 +57,14 @@ public RichTextPropertyEditor(ILogger logger, IUmbracoContextAccessor umbracoCon
internal class RichTextPropertyValueEditor : DataValueEditor, IDataValueReference
{
private IUmbracoContextAccessor _umbracoContextAccessor;
- private readonly ImageSourceParser _mediaParser;
- private readonly LocalLinkParser _localLinkParser;
+ private readonly HtmlImageSourceParser _imageSourceParser;
+ private readonly HtmlLocalLinkParser _localLinkParser;
- public RichTextPropertyValueEditor(DataEditorAttribute attribute, IUmbracoContextAccessor umbracoContextAccessor, ImageSourceParser mediaParser, LocalLinkParser localLinkParser)
+ public RichTextPropertyValueEditor(DataEditorAttribute attribute, IUmbracoContextAccessor umbracoContextAccessor, HtmlImageSourceParser imageSourceParser, HtmlLocalLinkParser localLinkParser)
: base(attribute)
{
_umbracoContextAccessor = umbracoContextAccessor;
- _mediaParser = mediaParser;
+ _imageSourceParser = imageSourceParser;
_localLinkParser = localLinkParser;
}
@@ -97,7 +97,7 @@ public override object ToEditor(Property property, IDataTypeService dataTypeServ
if (val == null)
return null;
- var propertyValueWithMediaResolved = _mediaParser.EnsureImageSources(val.ToString());
+ var propertyValueWithMediaResolved = _imageSourceParser.EnsureImageSources(val.ToString());
var parsed = MacroTagParser.FormatRichTextPersistedDataForEditor(propertyValueWithMediaResolved, new Dictionary());
return parsed;
}
@@ -119,8 +119,8 @@ public override object FromEditor(Core.Models.Editors.ContentPropertyData editor
var mediaParent = config?.MediaParentId;
var mediaParentId = mediaParent == null ? Guid.Empty : mediaParent.Guid;
- var parseAndSavedTempImages = _mediaParser.FindAndPersistPastedTempImages(editorValue.Value.ToString(), mediaParentId, userId);
- var editorValueWithMediaUrlsRemoved = _mediaParser.RemoveImageSources(parseAndSavedTempImages);
+ var parseAndSavedTempImages = _imageSourceParser.FindAndPersistPastedTempImages(editorValue.Value.ToString(), mediaParentId, userId);
+ var editorValueWithMediaUrlsRemoved = _imageSourceParser.RemoveImageSources(parseAndSavedTempImages);
var parsed = MacroTagParser.FormatRichTextContentForPersistence(editorValueWithMediaUrlsRemoved);
return parsed;
@@ -135,7 +135,7 @@ public IEnumerable GetReferences(object value)
{
var asString = value == null ? string.Empty : value is string str ? str : value.ToString();
- foreach (var udi in _mediaParser.FindUdisFromDataAttributes(asString))
+ foreach (var udi in _imageSourceParser.FindUdisFromDataAttributes(asString))
yield return udi;
foreach (var udi in _localLinkParser.FindUdisFromLocalLinks(asString))
diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs
index e8a2ac11a63e..c62a79d283e8 100644
--- a/src/Umbraco.Web/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs
+++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs
@@ -12,13 +12,13 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
[DefaultPropertyValueConverter]
public class MarkdownEditorValueConverter : PropertyValueConverterBase
{
- private readonly LocalLinkParser _localLinkParser;
- private readonly UrlParser _urlResolver;
+ private readonly HtmlLocalLinkParser _localLinkParser;
+ private readonly HtmlUrlParser _urlParser;
- public MarkdownEditorValueConverter(LocalLinkParser localLinkParser, UrlParser urlResolver)
+ public MarkdownEditorValueConverter(HtmlLocalLinkParser localLinkParser, HtmlUrlParser urlParser)
{
_localLinkParser = localLinkParser;
- _urlResolver = urlResolver;
+ _urlParser = urlParser;
}
public override bool IsConverter(IPublishedPropertyType propertyType)
@@ -37,7 +37,7 @@ public override object ConvertSourceToIntermediate(IPublishedElement owner, IPub
// ensures string is parsed for {localLink} and urls are resolved correctly
sourceString = _localLinkParser.EnsureInternalLinks(sourceString, preview);
- sourceString = _urlResolver.EnsureUrls(sourceString);
+ sourceString = _urlParser.EnsureUrls(sourceString);
return sourceString;
}
diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs
index 2caac9e1f483..3ab502742cc5 100644
--- a/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs
+++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs
@@ -24,9 +24,9 @@ public class RteMacroRenderingValueConverter : TinyMceValueConverter
{
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
private readonly IMacroRenderer _macroRenderer;
- private readonly LocalLinkParser _internalLinkParser;
- private readonly UrlParser _urlResolver;
- private readonly ImageSourceParser _mediaParser;
+ private readonly HtmlLocalLinkParser _linkParser;
+ private readonly HtmlUrlParser _urlParser;
+ private readonly HtmlImageSourceParser _imageSourceParser;
public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType)
{
@@ -36,13 +36,13 @@ public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType
}
public RteMacroRenderingValueConverter(IUmbracoContextAccessor umbracoContextAccessor, IMacroRenderer macroRenderer,
- LocalLinkParser internalLinkParser, UrlParser urlResolver, ImageSourceParser mediaParser)
+ HtmlLocalLinkParser linkParser, HtmlUrlParser urlParser, HtmlImageSourceParser imageSourceParser)
{
_umbracoContextAccessor = umbracoContextAccessor;
_macroRenderer = macroRenderer;
- _internalLinkParser = internalLinkParser;
- _urlResolver = urlResolver;
- _mediaParser = mediaParser;
+ _linkParser = linkParser;
+ _urlParser = urlParser;
+ _imageSourceParser = imageSourceParser;
}
// NOT thread-safe over a request because it modifies the
@@ -88,9 +88,9 @@ private string Convert(object source, bool preview)
var sourceString = source.ToString();
// ensures string is parsed for {localLink} and urls and media are resolved correctly
- sourceString = _internalLinkParser.EnsureInternalLinks(sourceString, preview);
- sourceString = _urlResolver.EnsureUrls(sourceString);
- sourceString = _mediaParser.EnsureImageSources(sourceString);
+ sourceString = _linkParser.EnsureInternalLinks(sourceString, preview);
+ sourceString = _urlParser.EnsureUrls(sourceString);
+ sourceString = _imageSourceParser.EnsureImageSources(sourceString);
// ensure string is parsed for macros and macros are executed correctly
sourceString = RenderRteMacros(sourceString, preview);
diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/TextStringValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/TextStringValueConverter.cs
index 5efc2ee2db07..939a658407d8 100644
--- a/src/Umbraco.Web/PropertyEditors/ValueConverters/TextStringValueConverter.cs
+++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/TextStringValueConverter.cs
@@ -11,9 +11,9 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
[DefaultPropertyValueConverter]
public class TextStringValueConverter : PropertyValueConverterBase
{
- public TextStringValueConverter(LocalLinkParser internalLinkParser, UrlParser urlParser)
+ public TextStringValueConverter(HtmlLocalLinkParser linkParser, HtmlUrlParser urlParser)
{
- _internalLinkParser = internalLinkParser;
+ _linkParser = linkParser;
_urlParser = urlParser;
}
@@ -22,8 +22,8 @@ public TextStringValueConverter(LocalLinkParser internalLinkParser, UrlParser ur
Constants.PropertyEditors.Aliases.TextBox,
Constants.PropertyEditors.Aliases.TextArea
};
- private readonly LocalLinkParser _internalLinkParser;
- private readonly UrlParser _urlParser;
+ private readonly HtmlLocalLinkParser _linkParser;
+ private readonly HtmlUrlParser _urlParser;
public override bool IsConverter(IPublishedPropertyType propertyType)
=> PropertyTypeAliases.Contains(propertyType.EditorAlias);
@@ -40,7 +40,7 @@ public override object ConvertSourceToIntermediate(IPublishedElement owner, IPub
var sourceString = source.ToString();
// ensures string is parsed for {localLink} and urls are resolved correctly
- sourceString = _internalLinkParser.EnsureInternalLinks(sourceString, preview);
+ sourceString = _linkParser.EnsureInternalLinks(sourceString, preview);
sourceString = _urlParser.EnsureUrls(sourceString);
return sourceString;
diff --git a/src/Umbraco.Web/Runtime/WebInitialComposer.cs b/src/Umbraco.Web/Runtime/WebInitialComposer.cs
index 2f78ac97329b..5ccb16a1a506 100644
--- a/src/Umbraco.Web/Runtime/WebInitialComposer.cs
+++ b/src/Umbraco.Web/Runtime/WebInitialComposer.cs
@@ -107,9 +107,9 @@ public override void Compose(Composition composition)
composition.RegisterUnique();
composition.RegisterUnique();
- composition.RegisterUnique();
- composition.RegisterUnique();
- composition.RegisterUnique();
+ composition.RegisterUnique();
+ composition.RegisterUnique();
+ composition.RegisterUnique();
// register the umbraco helper - this is Transient! very important!
// also, if not level.Run, we cannot really use the helper (during upgrade...)
diff --git a/src/Umbraco.Web/Templates/ImageSourceParser.cs b/src/Umbraco.Web/Templates/HtmlImageSourceParser.cs
similarity index 92%
rename from src/Umbraco.Web/Templates/ImageSourceParser.cs
rename to src/Umbraco.Web/Templates/HtmlImageSourceParser.cs
index 6a0bba499844..b36542167c3b 100644
--- a/src/Umbraco.Web/Templates/ImageSourceParser.cs
+++ b/src/Umbraco.Web/Templates/HtmlImageSourceParser.cs
@@ -14,9 +14,9 @@
namespace Umbraco.Web.Templates
{
- public sealed class ImageSourceParser
+ public sealed class HtmlImageSourceParser
{
- public ImageSourceParser(IUmbracoContextAccessor umbracoContextAccessor, ILogger logger, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider)
+ public HtmlImageSourceParser(IUmbracoContextAccessor umbracoContextAccessor, ILogger logger, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider)
{
_umbracoContextAccessor = umbracoContextAccessor;
_logger = logger;
@@ -99,10 +99,17 @@ public string EnsureImageSources(string text)
///
///
///
- internal string RemoveImageSources(string text)
+ public string RemoveImageSources(string text)
// see comment in ResolveMediaFromTextString for group reference
=> ResolveImgPattern.Replace(text, "$1$3$4$5");
+ ///
+ /// Used by the RTE (and grid RTE) for drag/drop/persisting images
+ ///
+ ///
+ ///
+ ///
+ ///
internal string FindAndPersistPastedTempImages(string html, Guid mediaParentFolder, int userId)
{
// Find all img's that has data-tmpimg attribute
@@ -199,7 +206,7 @@ internal string FindAndPersistPastedTempImages(string html, Guid mediaParentFold
}
catch (Exception ex)
{
- _logger.Error(typeof(ImageSourceParser), ex, "Could not delete temp file or folder {FileName}", absoluteTempImagePath);
+ _logger.Error(typeof(HtmlImageSourceParser), ex, "Could not delete temp file or folder {FileName}", absoluteTempImagePath);
}
}
}
diff --git a/src/Umbraco.Web/Templates/LocalLinkParser.cs b/src/Umbraco.Web/Templates/HtmlLocalLinkParser.cs
similarity index 97%
rename from src/Umbraco.Web/Templates/LocalLinkParser.cs
rename to src/Umbraco.Web/Templates/HtmlLocalLinkParser.cs
index f394f56d854e..f65a7183b751 100644
--- a/src/Umbraco.Web/Templates/LocalLinkParser.cs
+++ b/src/Umbraco.Web/Templates/HtmlLocalLinkParser.cs
@@ -11,7 +11,7 @@ namespace Umbraco.Web.Templates
///
/// Utility class used to parse internal links
///
- public sealed class LocalLinkParser
+ public sealed class HtmlLocalLinkParser
{
private static readonly Regex LocalLinkPattern = new Regex(@"href=""[/]?(?:\{|\%7B)localLink:([a-zA-Z0-9-://]+)(?:\}|\%7D)",
@@ -19,7 +19,7 @@ public sealed class LocalLinkParser
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
- public LocalLinkParser(IUmbracoContextAccessor umbracoContextAccessor)
+ public HtmlLocalLinkParser(IUmbracoContextAccessor umbracoContextAccessor)
{
_umbracoContextAccessor = umbracoContextAccessor;
}
diff --git a/src/Umbraco.Web/Templates/UrlParser.cs b/src/Umbraco.Web/Templates/HtmlUrlParser.cs
similarity index 95%
rename from src/Umbraco.Web/Templates/UrlParser.cs
rename to src/Umbraco.Web/Templates/HtmlUrlParser.cs
index e5c40b73655d..5b78477579ed 100644
--- a/src/Umbraco.Web/Templates/UrlParser.cs
+++ b/src/Umbraco.Web/Templates/HtmlUrlParser.cs
@@ -5,7 +5,7 @@
namespace Umbraco.Web.Templates
{
- public sealed class UrlParser
+ public sealed class HtmlUrlParser
{
private readonly IContentSection _contentSection;
private readonly IProfilingLogger _logger;
@@ -13,7 +13,7 @@ public sealed class UrlParser
private static readonly Regex ResolveUrlPattern = new Regex("(=[\"\']?)(\\W?\\~(?:.(?![\"\']?\\s+(?:\\S+)=|[>\"\']))+.)[\"\']?",
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
- public UrlParser(IContentSection contentSection, IProfilingLogger logger)
+ public HtmlUrlParser(IContentSection contentSection, IProfilingLogger logger)
{
_contentSection = contentSection;
_logger = logger;
diff --git a/src/Umbraco.Web/Templates/TemplateUtilities.cs b/src/Umbraco.Web/Templates/TemplateUtilities.cs
index db0366dbf3d5..bcc669186468 100644
--- a/src/Umbraco.Web/Templates/TemplateUtilities.cs
+++ b/src/Umbraco.Web/Templates/TemplateUtilities.cs
@@ -15,10 +15,10 @@
namespace Umbraco.Web.Templates
{
- [Obsolete("This class is obsolete, all methods have been moved to other classes such as InternalLinkHelper, UrlResolver and MediaParser")]
+ [Obsolete("This class is obsolete, all methods have been moved to other classes: HtmlLocalLinkParser, HtmlUrlParser and HtmlImageSourceParser")]
public static class TemplateUtilities
{
- [Obsolete("Inject and use an instance of InternalLinkParser instead")]
+ [Obsolete("Inject and use an instance of HtmlLocalLinkParser instead")]
internal static string ParseInternalLinks(string text, bool preview, UmbracoContext umbracoContext)
{
using (umbracoContext.ForcedPreview(preview)) // force for url provider
@@ -29,28 +29,28 @@ internal static string ParseInternalLinks(string text, bool preview, UmbracoCont
return text;
}
- [Obsolete("Inject and use an instance of InternalLinkParser instead")]
+ [Obsolete("Inject and use an instance of HtmlLocalLinkParser instead")]
public static string ParseInternalLinks(string text, UrlProvider urlProvider)
- => Current.Factory.GetInstance().EnsureInternalLinks(text);
+ => Current.Factory.GetInstance().EnsureInternalLinks(text);
- [Obsolete("Inject and use an instance of UrlResolver")]
+ [Obsolete("Inject and use an instance of HtmlUrlParser")]
public static string ResolveUrlsFromTextString(string text)
- => Current.Factory.GetInstance().EnsureUrls(text);
+ => Current.Factory.GetInstance().EnsureUrls(text);
[Obsolete("Use StringExtensions.CleanForXss instead")]
public static string CleanForXss(string text, params char[] ignoreFromClean)
=> text.CleanForXss(ignoreFromClean);
- [Obsolete("Use MediaParser.EnsureImageSources instead")]
+ [Obsolete("Use HtmlImageSourceParser.EnsureImageSources instead")]
public static string ResolveMediaFromTextString(string text)
- => Current.Factory.GetInstance().EnsureImageSources(text);
+ => Current.Factory.GetInstance().EnsureImageSources(text);
- [Obsolete("Use MediaParser.RemoveImageSources instead")]
+ [Obsolete("Use HtmlImageSourceParser.RemoveImageSources instead")]
internal static string RemoveMediaUrlsFromTextString(string text)
- => Current.Factory.GetInstance().RemoveImageSources(text);
+ => Current.Factory.GetInstance().RemoveImageSources(text);
- [Obsolete("Use MediaParser.RemoveImageSources instead")]
+ [Obsolete("Use HtmlImageSourceParser.FindAndPersistPastedTempImages instead")]
internal static string FindAndPersistPastedTempImages(string html, Guid mediaParentFolder, int userId, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, ILogger logger)
- => Current.Factory.GetInstance().FindAndPersistPastedTempImages(html, mediaParentFolder, userId);
+ => Current.Factory.GetInstance().FindAndPersistPastedTempImages(html, mediaParentFolder, userId);
}
}
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 8fc06c75c273..84645f3b2d09 100755
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -247,9 +247,9 @@
-
-
-
+
+
+
diff --git a/src/Umbraco.Web/UmbracoComponentRenderer.cs b/src/Umbraco.Web/UmbracoComponentRenderer.cs
index 83c8a7f0faa1..01c696fd2d5a 100644
--- a/src/Umbraco.Web/UmbracoComponentRenderer.cs
+++ b/src/Umbraco.Web/UmbracoComponentRenderer.cs
@@ -27,14 +27,14 @@ internal class UmbracoComponentRenderer : IUmbracoComponentRenderer
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
private readonly IMacroRenderer _macroRenderer;
private readonly ITemplateRenderer _templateRenderer;
- private readonly LocalLinkParser _internalLinkParser;
+ private readonly HtmlLocalLinkParser _linkParser;
- public UmbracoComponentRenderer(IUmbracoContextAccessor umbracoContextAccessor, IMacroRenderer macroRenderer, ITemplateRenderer templateRenderer, LocalLinkParser internalLinkParser)
+ public UmbracoComponentRenderer(IUmbracoContextAccessor umbracoContextAccessor, IMacroRenderer macroRenderer, ITemplateRenderer templateRenderer, HtmlLocalLinkParser linkParser)
{
_umbracoContextAccessor = umbracoContextAccessor;
_macroRenderer = macroRenderer;
_templateRenderer = templateRenderer ?? throw new ArgumentNullException(nameof(templateRenderer));
- _internalLinkParser = internalLinkParser;
+ _linkParser = linkParser;
}
///
@@ -159,7 +159,7 @@ private IHtmlString RenderMacro(string alias, IDictionary parame
_umbracoContextAccessor.UmbracoContext.HttpContext.Response.ContentType = contentType;
//Now, we need to ensure that local links are parsed
- html = _internalLinkParser.EnsureInternalLinks(output.ToString());
+ html = _linkParser.EnsureInternalLinks(output.ToString());
}
}
From ba8c1df017d1595abfeee2dbb659b116406fdcd3 Mon Sep 17 00:00:00 2001
From: Shannon
Date: Wed, 23 Oct 2019 15:38:14 +1100
Subject: [PATCH 14/15] fixing tests
---
src/Umbraco.Tests/Testing/UmbracoTestBase.cs | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs
index 7e72a5aefbd6..ec265bd540c5 100644
--- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs
+++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs
@@ -41,6 +41,7 @@
using Umbraco.Web.Sections;
using Current = Umbraco.Core.Composing.Current;
using FileSystems = Umbraco.Core.IO.FileSystems;
+using Umbraco.Web.Templates;
namespace Umbraco.Tests.Testing
{
@@ -230,6 +231,10 @@ protected virtual void ComposeWeb()
.Append();
Composition.RegisterUnique();
+ Composition.RegisterUnique();
+ Composition.RegisterUnique();
+ Composition.RegisterUnique();
+
}
protected virtual void ComposeMisc()
From c831c9de53b59a39734f3f38e06f89031cfb9b69 Mon Sep 17 00:00:00 2001
From: Shannon
Date: Wed, 23 Oct 2019 16:30:22 +1100
Subject: [PATCH 15/15] uses nameof in attributes
---
src/Umbraco.Web/Templates/TemplateUtilities.cs | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/Umbraco.Web/Templates/TemplateUtilities.cs b/src/Umbraco.Web/Templates/TemplateUtilities.cs
index bcc669186468..62d25fa7941c 100644
--- a/src/Umbraco.Web/Templates/TemplateUtilities.cs
+++ b/src/Umbraco.Web/Templates/TemplateUtilities.cs
@@ -15,10 +15,10 @@
namespace Umbraco.Web.Templates
{
- [Obsolete("This class is obsolete, all methods have been moved to other classes: HtmlLocalLinkParser, HtmlUrlParser and HtmlImageSourceParser")]
+ [Obsolete("This class is obsolete, all methods have been moved to other classes: " + nameof(HtmlLocalLinkParser) + ", " + nameof(HtmlUrlParser) + " and " + nameof(HtmlImageSourceParser))]
public static class TemplateUtilities
{
- [Obsolete("Inject and use an instance of HtmlLocalLinkParser instead")]
+ [Obsolete("Inject and use an instance of " + nameof(HtmlLocalLinkParser) + " instead")]
internal static string ParseInternalLinks(string text, bool preview, UmbracoContext umbracoContext)
{
using (umbracoContext.ForcedPreview(preview)) // force for url provider
@@ -29,27 +29,27 @@ internal static string ParseInternalLinks(string text, bool preview, UmbracoCont
return text;
}
- [Obsolete("Inject and use an instance of HtmlLocalLinkParser instead")]
+ [Obsolete("Inject and use an instance of " + nameof(HtmlLocalLinkParser) + " instead")]
public static string ParseInternalLinks(string text, UrlProvider urlProvider)
=> Current.Factory.GetInstance().EnsureInternalLinks(text);
- [Obsolete("Inject and use an instance of HtmlUrlParser")]
+ [Obsolete("Inject and use an instance of " + nameof(HtmlUrlParser))]
public static string ResolveUrlsFromTextString(string text)
=> Current.Factory.GetInstance().EnsureUrls(text);
- [Obsolete("Use StringExtensions.CleanForXss instead")]
+ [Obsolete("Use " + nameof(StringExtensions) + "." + nameof(StringExtensions.CleanForXss) + " instead")]
public static string CleanForXss(string text, params char[] ignoreFromClean)
=> text.CleanForXss(ignoreFromClean);
- [Obsolete("Use HtmlImageSourceParser.EnsureImageSources instead")]
+ [Obsolete("Use " + nameof(HtmlImageSourceParser) + "." + nameof(HtmlImageSourceParser.EnsureImageSources) + " instead")]
public static string ResolveMediaFromTextString(string text)
=> Current.Factory.GetInstance().EnsureImageSources(text);
- [Obsolete("Use HtmlImageSourceParser.RemoveImageSources instead")]
+ [Obsolete("Use " + nameof(HtmlImageSourceParser) + "." + nameof(HtmlImageSourceParser.RemoveImageSources) + " instead")]
internal static string RemoveMediaUrlsFromTextString(string text)
=> Current.Factory.GetInstance().RemoveImageSources(text);
- [Obsolete("Use HtmlImageSourceParser.FindAndPersistPastedTempImages instead")]
+ [Obsolete("Use " + nameof(HtmlImageSourceParser) + "." + nameof(HtmlImageSourceParser.FindAndPersistPastedTempImages) + " instead")]
internal static string FindAndPersistPastedTempImages(string html, Guid mediaParentFolder, int userId, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, ILogger logger)
=> Current.Factory.GetInstance().FindAndPersistPastedTempImages(html, mediaParentFolder, userId);
}