Merge pull request #7228 from umbraco/v8/feature/community-package-tracking

V8 - Community package tracking of references
This commit is contained in:
Shannon Deminick
2019-12-05 23:44:15 +11:00
committed by GitHub
32 changed files with 170 additions and 78 deletions

View File

@@ -154,6 +154,9 @@ namespace Umbraco.Core.Composing
public static DataEditorCollection DataEditors
=> Factory.GetInstance<DataEditorCollection>();
public static DataValueReferenceFactoryCollection DataValueReferenceFactories
=> Factory.GetInstance<DataValueReferenceFactoryCollection>();
public static PropertyEditorCollection PropertyEditors
=> Factory.GetInstance<PropertyEditorCollection>();

View File

@@ -49,6 +49,13 @@ namespace Umbraco.Core
public static DataEditorCollectionBuilder DataEditors(this Composition composition)
=> composition.WithCollectionBuilder<DataEditorCollectionBuilder>();
/// <summary>
/// Gets the data value reference factory collection builder.
/// </summary>
/// <param name="composition">The composition.</param>
public static DataValueReferenceFactoryCollectionBuilder DataValueReferenceFactories(this Composition composition)
=> composition.WithCollectionBuilder<DataValueReferenceFactoryCollectionBuilder>();
/// <summary>
/// Gets the property value converters collection builder.
/// </summary>

View File

@@ -36,6 +36,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
where TRepository : class, IRepository
{
private readonly Lazy<PropertyEditorCollection> _propertyEditors;
private readonly DataValueReferenceFactoryCollection _dataValueReferenceFactories;
/// <summary>
///
@@ -49,13 +50,14 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
/// </param>
protected ContentRepositoryBase(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger,
ILanguageRepository languageRepository, IRelationRepository relationRepository, IRelationTypeRepository relationTypeRepository,
Lazy<PropertyEditorCollection> propertyEditors)
Lazy<PropertyEditorCollection> propertyEditors, DataValueReferenceFactoryCollection dataValueReferenceFactories)
: base(scopeAccessor, cache, logger)
{
LanguageRepository = languageRepository;
RelationRepository = relationRepository;
RelationTypeRepository = relationTypeRepository;
_propertyEditors = propertyEditors;
_dataValueReferenceFactories = dataValueReferenceFactories;
}
protected abstract TRepository This { get; }
@@ -821,21 +823,10 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected void PersistRelations(TEntity entity)
{
// Get all references from our core built in DataEditors/Property Editors
// Along with seeing if deverlopers want to collect additional references from the DataValueReferenceFactories collection
var trackedRelations = new List<UmbracoEntityReference>();
foreach (var p in entity.Properties)
{
if (!PropertyEditors.TryGet(p.PropertyType.PropertyEditorAlias, out var editor)) continue;
var valueEditor = editor.GetValueEditor();
if (!(valueEditor is IDataValueReference reference)) continue;
//TODO: Support variants/segments! This is not required for this initial prototype which is why there is a check here
if (!p.PropertyType.VariesByNothing()) continue;
var val = p.GetValue(); // get the invariant value
var refs = reference.GetReferences(val);
trackedRelations.AddRange(refs);
}
trackedRelations.AddRange(_dataValueReferenceFactories.GetAllReferences(entity.Properties, PropertyEditors));
//First delete all auto-relations for this entity
RelationRepository.DeleteByParent(entity.Id, Constants.Conventions.RelationTypes.AutomaticRelationTypes);

View File

@@ -20,8 +20,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
{
public DocumentBlueprintRepository(IScopeAccessor scopeAccessor, AppCaches appCaches, ILogger logger,
IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, ITagRepository tagRepository, ILanguageRepository languageRepository, IRelationRepository relationRepository, IRelationTypeRepository relationTypeRepository,
Lazy<PropertyEditorCollection> propertyEditorCollection)
: base(scopeAccessor, appCaches, logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditorCollection)
Lazy<PropertyEditorCollection> propertyEditorCollection, DataValueReferenceFactoryCollection dataValueReferenceFactories)
: base(scopeAccessor, appCaches, logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditorCollection, dataValueReferenceFactories)
{
}

View File

@@ -46,8 +46,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
/// </param>
public DocumentRepository(IScopeAccessor scopeAccessor, AppCaches appCaches, ILogger logger,
IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, ITagRepository tagRepository, ILanguageRepository languageRepository, IRelationRepository relationRepository, IRelationTypeRepository relationTypeRepository,
Lazy<PropertyEditorCollection> propertyEditors)
: base(scopeAccessor, appCaches, logger, languageRepository, relationRepository, relationTypeRepository, propertyEditors)
Lazy<PropertyEditorCollection> propertyEditors, DataValueReferenceFactoryCollection dataValueReferenceFactories)
: base(scopeAccessor, appCaches, logger, languageRepository, relationRepository, relationTypeRepository, propertyEditors, dataValueReferenceFactories)
{
_contentTypeRepository = contentTypeRepository ?? throw new ArgumentNullException(nameof(contentTypeRepository));
_templateRepository = templateRepository ?? throw new ArgumentNullException(nameof(templateRepository));

View File

@@ -29,8 +29,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
private readonly MediaByGuidReadRepository _mediaByGuidReadRepository;
public MediaRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IMediaTypeRepository mediaTypeRepository, ITagRepository tagRepository, ILanguageRepository languageRepository, IRelationRepository relationRepository, IRelationTypeRepository relationTypeRepository,
Lazy<PropertyEditorCollection> propertyEditorCollection)
: base(scopeAccessor, cache, logger, languageRepository, relationRepository, relationTypeRepository, propertyEditorCollection)
Lazy<PropertyEditorCollection> propertyEditorCollection, DataValueReferenceFactoryCollection dataValueReferenceFactories)
: base(scopeAccessor, cache, logger, languageRepository, relationRepository, relationTypeRepository, propertyEditorCollection, dataValueReferenceFactories)
{
_mediaTypeRepository = mediaTypeRepository ?? throw new ArgumentNullException(nameof(mediaTypeRepository));
_tagRepository = tagRepository ?? throw new ArgumentNullException(nameof(tagRepository));

View File

@@ -28,8 +28,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
public MemberRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger,
IMemberTypeRepository memberTypeRepository, IMemberGroupRepository memberGroupRepository, ITagRepository tagRepository, ILanguageRepository languageRepository, IRelationRepository relationRepository, IRelationTypeRepository relationTypeRepository,
Lazy<PropertyEditorCollection> propertyEditors)
: base(scopeAccessor, cache, logger, languageRepository, relationRepository, relationTypeRepository, propertyEditors)
Lazy<PropertyEditorCollection> propertyEditors, DataValueReferenceFactoryCollection dataValueReferenceFactories)
: base(scopeAccessor, cache, logger, languageRepository, relationRepository, relationTypeRepository, propertyEditors, dataValueReferenceFactories)
{
_memberTypeRepository = memberTypeRepository ?? throw new ArgumentNullException(nameof(memberTypeRepository));
_tagRepository = tagRepository ?? throw new ArgumentNullException(nameof(tagRepository));

View File

@@ -0,0 +1,52 @@
using System.Collections.Generic;
using Umbraco.Core.Composing;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Editors;
namespace Umbraco.Core.PropertyEditors
{
public class DataValueReferenceFactoryCollection : BuilderCollectionBase<IDataValueReferenceFactory>
{
public DataValueReferenceFactoryCollection(IEnumerable<IDataValueReferenceFactory> items)
: base(items)
{ }
public IEnumerable<UmbracoEntityReference> GetAllReferences(PropertyCollection properties, PropertyEditorCollection propertyEditors)
{
var trackedRelations = new List<UmbracoEntityReference>();
foreach (var p in properties)
{
// Injecting propertyEditorCollection is causing LightInject to throw a Recursive Dependancy error
// Hence using Current.PropertyEditors
if (!propertyEditors.TryGet(p.PropertyType.PropertyEditorAlias, out var editor)) continue;
//TODO: Support variants/segments! This is not required for this initial prototype which is why there is a check here
if (!p.PropertyType.VariesByNothing()) continue;
var val = p.GetValue(); // get the invariant value
var valueEditor = editor.GetValueEditor();
if (valueEditor is IDataValueReference reference)
{
var refs = reference.GetReferences(val);
trackedRelations.AddRange(refs);
}
// Loop over collection that may be add to existing property editors
// implementation of GetReferences in IDataValueReference.
// Allows developers to add support for references by a
// package /property editor that did not implement IDataValueReference themselves
foreach (var item in this)
{
// Check if this value reference is for this datatype/editor
// Then call it's GetReferences method - to see if the value stored
// in the dataeditor/property has referecnes to media/content items
if (item.IsForEditor(editor))
trackedRelations.AddRange(item.GetDataValueReference().GetReferences(val));
}
}
return trackedRelations;
}
}
}

View File

@@ -0,0 +1,9 @@
using Umbraco.Core.Composing;
namespace Umbraco.Core.PropertyEditors
{
public class DataValueReferenceFactoryCollectionBuilder : OrderedCollectionBuilderBase<DataValueReferenceFactoryCollectionBuilder, DataValueReferenceFactoryCollection, IDataValueReferenceFactory>
{
protected override DataValueReferenceFactoryCollectionBuilder This => this;
}
}

View File

@@ -13,6 +13,6 @@ namespace Umbraco.Core.PropertyEditors
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
IEnumerable<UmbracoEntityReference> GetReferences(object value);
IEnumerable<UmbracoEntityReference> GetReferences(object value);
}
}

View File

@@ -0,0 +1,18 @@
namespace Umbraco.Core.PropertyEditors
{
public interface IDataValueReferenceFactory
{
/// <summary>
/// Gets a value indicating whether the DataValueReference lookup supports a datatype (data editor).
/// </summary>
/// <param name="dataType">The datatype.</param>
/// <returns>A value indicating whether the converter supports a datatype.</returns>
bool IsForEditor(IDataEditor dataEditor);
/// <summary>
///
/// </summary>
/// <returns></returns>
IDataValueReference GetDataValueReference();
}
}

View File

@@ -43,7 +43,7 @@ namespace Umbraco.Core.Runtime
// register persistence mappers - required by database factory so needs to be done here
// means the only place the collection can be modified is in a runtime - afterwards it
// has been frozen and it is too late
composition.WithCollectionBuilder<MapperCollectionBuilder>().AddCoreMappers();
composition.Mappers().AddCoreMappers();
// register the scope provider
composition.RegisterUnique<ScopeProvider>(); // implements both IScopeProvider and IScopeAccessor
@@ -70,11 +70,15 @@ namespace Umbraco.Core.Runtime
composition.ManifestFilters();
// properties and parameters derive from data editors
composition.WithCollectionBuilder<DataEditorCollectionBuilder>()
composition.DataEditors()
.Add(() => composition.TypeLoader.GetDataEditors());
composition.RegisterUnique<PropertyEditorCollection>();
composition.RegisterUnique<ParameterEditorCollection>();
// Used to determine if a datatype/editor should be storing/tracking
// references to media item/s
composition.DataValueReferenceFactories();
// register a server registrar, by default it's the db registrar
composition.RegisterUnique<IServerRegistrar>(f =>
{
@@ -101,13 +105,13 @@ namespace Umbraco.Core.Runtime
factory.GetInstance<IGlobalSettings>(),
true, new DatabaseServerMessengerOptions()));
composition.WithCollectionBuilder<CacheRefresherCollectionBuilder>()
composition.CacheRefreshers()
.Add(() => composition.TypeLoader.GetCacheRefreshers());
composition.WithCollectionBuilder<PackageActionCollectionBuilder>()
composition.PackageActions()
.Add(() => composition.TypeLoader.GetPackageActions());
composition.WithCollectionBuilder<PropertyValueConverterCollectionBuilder>()
composition.PropertyValueConverters()
.Append(composition.TypeLoader.GetTypes<IPropertyValueConverter>());
composition.RegisterUnique<IPublishedContentTypeFactory, PublishedContentTypeFactory>();
@@ -115,7 +119,7 @@ namespace Umbraco.Core.Runtime
composition.RegisterUnique<IShortStringHelper>(factory
=> new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(factory.GetInstance<IUmbracoSettingsSection>())));
composition.WithCollectionBuilder<UrlSegmentProviderCollectionBuilder>()
composition.UrlSegmentProviders()
.Append<DefaultUrlSegmentProvider>();
composition.RegisterUnique<IMigrationBuilder>(factory => new MigrationBuilder(factory));

View File

@@ -281,7 +281,10 @@
<Compile Include="Models\PublishedContent\IPublishedContentType.cs" />
<Compile Include="Models\PublishedContent\IPublishedPropertyType.cs" />
<Compile Include="PropertyEditors\ConfigurationFieldsExtensions.cs" />
<Compile Include="PropertyEditors\DataValueReferenceFactoryCollection.cs" />
<Compile Include="PropertyEditors\DataValueReferenceFactoryCollectionBuilder.cs" />
<Compile Include="PropertyEditors\IDataValueReference.cs" />
<Compile Include="PropertyEditors\IDataValueReferenceFactory.cs" />
<Compile Include="PropertyEditors\IIgnoreUserStartNodesConfig.cs" />
<Compile Include="PublishedContentExtensions.cs" />
<Compile Include="Models\PublishedContent\UrlMode.cs" />

View File

@@ -40,7 +40,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var entityRepository = new EntityRepository(scopeAccessor);
var relationRepository = new RelationRepository(scopeAccessor, Logger, relationTypeRepository, entityRepository);
var propertyEditors = new Lazy<PropertyEditorCollection>(() => new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty<IDataEditor>())));
var repository = new DocumentRepository(scopeAccessor, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditors);
var dataValueReferences = new DataValueReferenceFactoryCollection(Enumerable.Empty<IDataValueReferenceFactory>());
var repository = new DocumentRepository(scopeAccessor, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditors, dataValueReferences);
return repository;
}

View File

@@ -73,7 +73,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var entityRepository = new EntityRepository(scopeAccessor);
var relationRepository = new RelationRepository(scopeAccessor, Logger, relationTypeRepository, entityRepository);
var propertyEditors = new Lazy<PropertyEditorCollection>(() => new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty<IDataEditor>())));
var repository = new DocumentRepository(scopeAccessor, appCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditors);
var dataValueReferences = new DataValueReferenceFactoryCollection(Enumerable.Empty<IDataValueReferenceFactory>());
var repository = new DocumentRepository(scopeAccessor, appCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditors, dataValueReferences);
return repository;
}

View File

@@ -31,7 +31,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var entityRepository = new EntityRepository(accessor);
var relationRepository = new RelationRepository(accessor, Logger, relationTypeRepository, entityRepository);
var propertyEditors = new Lazy<PropertyEditorCollection>(() => new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty<IDataEditor>())));
documentRepository = new DocumentRepository(accessor, Core.Cache.AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditors);
var dataValueReferences = new DataValueReferenceFactoryCollection(Enumerable.Empty<IDataValueReferenceFactory>());
documentRepository = new DocumentRepository(accessor, Core.Cache.AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditors, dataValueReferences);
var domainRepository = new DomainRepository(accessor, Core.Cache.AppCaches.Disabled, Logger);
return domainRepository;
}

View File

@@ -46,7 +46,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var entityRepository = new EntityRepository(scopeAccessor);
var relationRepository = new RelationRepository(scopeAccessor, Logger, relationTypeRepository, entityRepository);
var propertyEditors = new Lazy<PropertyEditorCollection>(() => new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty<IDataEditor>())));
var repository = new MediaRepository(scopeAccessor, appCaches, Logger, mediaTypeRepository, tagRepository, Mock.Of<ILanguageRepository>(), relationRepository, relationTypeRepository, propertyEditors);
var dataValueReferences = new DataValueReferenceFactoryCollection(Enumerable.Empty<IDataValueReferenceFactory>());
var repository = new MediaRepository(scopeAccessor, appCaches, Logger, mediaTypeRepository, tagRepository, Mock.Of<ILanguageRepository>(), relationRepository, relationTypeRepository, propertyEditors, dataValueReferences);
return repository;
}

View File

@@ -40,7 +40,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var entityRepository = new EntityRepository(accessor);
var relationRepository = new RelationRepository(accessor, Logger, relationTypeRepository, entityRepository);
var propertyEditors = new Lazy<PropertyEditorCollection>(() => new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty<IDataEditor>())));
var repository = new MemberRepository(accessor, AppCaches.Disabled, Logger, memberTypeRepository, memberGroupRepository, tagRepo, Mock.Of<ILanguageRepository>(), relationRepository, relationTypeRepository, propertyEditors);
var dataValueReferences = new DataValueReferenceFactoryCollection(Enumerable.Empty<IDataValueReferenceFactory>());
var repository = new MemberRepository(accessor, AppCaches.Disabled, Logger, memberTypeRepository, memberGroupRepository, tagRepo, Mock.Of<ILanguageRepository>(), relationRepository, relationTypeRepository, propertyEditors, dataValueReferences);
return repository;
}

View File

@@ -315,7 +315,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var entityRepository = new EntityRepository(accessor);
var relationRepository = new RelationRepository(accessor, Logger, relationTypeRepository, entityRepository);
var propertyEditors = new Lazy<PropertyEditorCollection>(() => new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty<IDataEditor>())));
var repository = new DocumentRepository(accessor, AppCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditors);
var dataValueReferences = new DataValueReferenceFactoryCollection(Enumerable.Empty<IDataValueReferenceFactory>());
var repository = new DocumentRepository(accessor, AppCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditors, dataValueReferences);
return repository;
}

View File

@@ -964,7 +964,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var entityRepository = new EntityRepository(accessor);
var relationRepository = new RelationRepository(accessor, Logger, relationTypeRepository, entityRepository);
var propertyEditors = new Lazy<PropertyEditorCollection>(() => new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty<IDataEditor>())));
var repository = new DocumentRepository(accessor, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditors);
var dataValueReferences = new DataValueReferenceFactoryCollection(Enumerable.Empty<IDataValueReferenceFactory>());
var repository = new DocumentRepository(accessor, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditors, dataValueReferences);
return repository;
}
@@ -980,7 +981,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var entityRepository = new EntityRepository(accessor);
var relationRepository = new RelationRepository(accessor, Logger, relationTypeRepository, entityRepository);
var propertyEditors = new Lazy<PropertyEditorCollection>(() => new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty<IDataEditor>())));
var repository = new MediaRepository(accessor, AppCaches.Disabled, Logger, mediaTypeRepository, tagRepository, Mock.Of<ILanguageRepository>(), relationRepository, relationTypeRepository, propertyEditors);
var dataValueReferences = new DataValueReferenceFactoryCollection(Enumerable.Empty<IDataValueReferenceFactory>());
var repository = new MediaRepository(accessor, AppCaches.Disabled, Logger, mediaTypeRepository, tagRepository, Mock.Of<ILanguageRepository>(), relationRepository, relationTypeRepository, propertyEditors, dataValueReferences);
return repository;
}
}

View File

@@ -246,7 +246,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var entityRepository = new EntityRepository(ScopeProvider);
var relationRepository = new RelationRepository(ScopeProvider, Logger, relationTypeRepository, entityRepository);
var propertyEditors = new Lazy<PropertyEditorCollection>(() => new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty<IDataEditor>())));
var contentRepo = new DocumentRepository(ScopeProvider, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditors);
var dataValueReferences = new DataValueReferenceFactoryCollection(Enumerable.Empty<IDataValueReferenceFactory>());
var contentRepo = new DocumentRepository(ScopeProvider, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditors, dataValueReferences);
var contentType = MockedContentTypes.CreateSimpleContentType("umbTextpage2", "Textpage");
ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType!

View File

@@ -35,7 +35,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var entityRepository = new EntityRepository(accessor);
var relationRepository = new RelationRepository(accessor, Logger, relationTypeRepository, entityRepository);
var propertyEditors = new Lazy<PropertyEditorCollection>(() => new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty<IDataEditor>())));
var repository = new MediaRepository(accessor, AppCaches, Mock.Of<ILogger>(), mediaTypeRepository, tagRepository, Mock.Of<ILanguageRepository>(), relationRepository, relationTypeRepository, propertyEditors);
var dataValueReferences = new DataValueReferenceFactoryCollection(Enumerable.Empty<IDataValueReferenceFactory>());
var repository = new MediaRepository(accessor, AppCaches, Mock.Of<ILogger>(), mediaTypeRepository, tagRepository, Mock.Of<ILanguageRepository>(), relationRepository, relationTypeRepository, propertyEditors, dataValueReferences);
return repository;
}
@@ -57,7 +58,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var entityRepository = new EntityRepository(accessor);
var relationRepository = new RelationRepository(accessor, Logger, relationTypeRepository, entityRepository);
var propertyEditors = new Lazy<PropertyEditorCollection>(() => new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty<IDataEditor>())));
var repository = new DocumentRepository(accessor, AppCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditors);
var dataValueReferences = new DataValueReferenceFactoryCollection(Enumerable.Empty<IDataValueReferenceFactory>());
var repository = new DocumentRepository(accessor, AppCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditors, dataValueReferences);
return repository;
}

View File

@@ -52,7 +52,8 @@ namespace Umbraco.Tests.Services
var entityRepository = new EntityRepository(accessor);
var relationRepository = new RelationRepository(accessor, Logger, relationTypeRepository, entityRepository);
var propertyEditors = new Lazy<PropertyEditorCollection>(() => new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty<IDataEditor>())));
var repository = new DocumentRepository(accessor, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository, relationRepository, relationTypeRepository, propertyEditors);
var dataValueReferences = new DataValueReferenceFactoryCollection(Enumerable.Empty<IDataValueReferenceFactory>());
var repository = new DocumentRepository(accessor, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository, relationRepository, relationTypeRepository, propertyEditors, dataValueReferences);
return repository;
}

View File

@@ -3211,7 +3211,8 @@ namespace Umbraco.Tests.Services
var entityRepository = new EntityRepository(accessor);
var relationRepository = new RelationRepository(accessor, Logger, relationTypeRepository, entityRepository);
var propertyEditors = new Lazy<PropertyEditorCollection>(() => new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty<IDataEditor>())));
var repository = new DocumentRepository(accessor, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditors);
var dataValueReferences = new DataValueReferenceFactoryCollection(Enumerable.Empty<IDataValueReferenceFactory>());
var repository = new DocumentRepository(accessor, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository, relationRepository, relationTypeRepository, propertyEditors, dataValueReferences);
return repository;
}

View File

@@ -217,6 +217,9 @@ namespace Umbraco.Tests.Testing
Composition.RegisterUnique(_ => Umbraco.Web.Composing.Current.UmbracoContextAccessor);
Composition.RegisterUnique<IPublishedRouter, PublishedRouter>();
Composition.WithCollectionBuilder<ContentFinderCollectionBuilder>();
Composition.DataValueReferenceFactories();
Composition.RegisterUnique<IContentLastChanceFinder, TestLastChanceFinder>();
Composition.RegisterUnique<IVariationContextAccessor, TestVariationContextAccessor>();
Composition.RegisterUnique<IPublishedSnapshotAccessor, TestPublishedSnapshotAccessor>();

View File

@@ -182,6 +182,8 @@ namespace Umbraco.Web.Composing
public static DataEditorCollection DataEditors => CoreCurrent.DataEditors;
public static DataValueReferenceFactoryCollection DataValueReferenceFactories => CoreCurrent.DataValueReferenceFactories;
public static PropertyEditorCollection PropertyEditors => CoreCurrent.PropertyEditors;
public static ParameterEditorCollection ParameterEditors => CoreCurrent.ParameterEditors;

View File

@@ -165,20 +165,15 @@ namespace Umbraco.Web.PropertyEditors
public IEnumerable<UmbracoEntityReference> GetReferences(object value)
{
var rawJson = value == null ? string.Empty : value is string str ? str : value.ToString();
DeserializeGridValue(rawJson, out var richTextEditorValues, out var mediaValues);
foreach (var umbracoEntityReference in richTextEditorValues.SelectMany(x =>
_richTextPropertyValueEditor.GetReferences(x.Value)))
{
yield return umbracoEntityReference;
}
foreach (var umbracoEntityReference in mediaValues.SelectMany(x =>
_mediaPickerPropertyValueEditor.GetReferences(x.Value["udi"])))
{
yield return umbracoEntityReference;
}
}
}
}

View File

@@ -36,11 +36,8 @@ namespace Umbraco.Web.PropertyEditors
var udiPaths = asString.Split(',');
foreach (var udiPath in udiPaths)
{
if (Udi.TryParse(udiPath, out var udi))
yield return new UmbracoEntityReference(udi);
}
}
}
}

View File

@@ -4,6 +4,9 @@ using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Logging;
using Umbraco.Core.Services;
using Umbraco.Web.PublishedCache;
using System.Collections.Generic;
using Umbraco.Core.Models.Editors;
using Newtonsoft.Json;
namespace Umbraco.Web.PropertyEditors
{
@@ -25,7 +28,7 @@ namespace Umbraco.Web.PropertyEditors
_entityService = entityService ?? throw new ArgumentNullException(nameof(entityService));
_publishedSnapshotAccessor = publishedSnapshotAccessor ?? throw new ArgumentNullException(nameof(publishedSnapshotAccessor));
}
protected override IConfigurationEditor CreateConfigurationEditor() => new MultiUrlPickerConfigurationEditor();
protected override IDataValueEditor CreateValueEditor() => new MultiUrlPickerValueEditor(_entityService, _publishedSnapshotAccessor, Logger, Attribute);

View File

@@ -190,9 +190,6 @@ namespace Umbraco.Web.PropertyEditors
}
}
}
}
}

View File

@@ -227,6 +227,7 @@ namespace Umbraco.Web.PropertyEditors
// return json
return JsonConvert.SerializeObject(deserialized);
}
#endregion
public IEnumerable<UmbracoEntityReference> GetReferences(object value)
{
@@ -252,8 +253,6 @@ namespace Umbraco.Web.PropertyEditors
return result;
}
#endregion
}
internal class NestedContentValidator : IValueValidator

View File

@@ -9,9 +9,7 @@ using Umbraco.Core.Dashboards;
using Umbraco.Core.Dictionary;
using Umbraco.Core.Events;
using Umbraco.Core.Migrations.PostMigrations;
using Umbraco.Web.Migrations.PostMigrations;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.PropertyEditors.ValueConverters;
using Umbraco.Core.Runtime;
using Umbraco.Core.Services;
@@ -19,7 +17,6 @@ using Umbraco.Web.Actions;
using Umbraco.Web.Cache;
using Umbraco.Web.Composing.CompositionExtensions;
using Umbraco.Web.ContentApps;
using Umbraco.Web.Dashboards;
using Umbraco.Web.Dictionary;
using Umbraco.Web.Editors;
using Umbraco.Web.Features;
@@ -37,7 +34,6 @@ using Umbraco.Web.Security.Providers;
using Umbraco.Web.Services;
using Umbraco.Web.SignalR;
using Umbraco.Web.Templates;
using Umbraco.Web.Tour;
using Umbraco.Web.Trees;
using Umbraco.Web.WebApi;
using Current = Umbraco.Web.Composing.Current;
@@ -150,19 +146,19 @@ namespace Umbraco.Web.Runtime
.ComposeUmbracoControllers(GetType().Assembly)
.SetDefaultRenderMvcController<RenderMvcController>(); // default controller for template views
composition.WithCollectionBuilder<SearchableTreeCollectionBuilder>()
composition.SearchableTrees()
.Add(() => composition.TypeLoader.GetTypes<ISearchableTree>());
composition.Register<UmbracoTreeSearcher>(Lifetime.Request);
composition.WithCollectionBuilder<EditorValidatorCollectionBuilder>()
composition.EditorValidators()
.Add(() => composition.TypeLoader.GetTypes<IEditorValidator>());
composition.WithCollectionBuilder<TourFilterCollectionBuilder>();
composition.TourFilters();
composition.RegisterUnique<UmbracoFeatures>();
composition.WithCollectionBuilder<ActionCollectionBuilder>()
composition.Actions()
.Add(() => composition.TypeLoader.GetTypes<IAction>());
//we need to eagerly scan controller types since they will need to be routed
@@ -177,26 +173,26 @@ namespace Umbraco.Web.Runtime
// here because there cannot be two converters for one property editor - and we want the full
// RteMacroRenderingValueConverter that converts macros, etc. So remove TinyMceValueConverter.
// (the limited one, defined in Core, is there for tests) - same for others
composition.WithCollectionBuilder<PropertyValueConverterCollectionBuilder>()
composition.PropertyValueConverters()
.Remove<TinyMceValueConverter>()
.Remove<TextStringValueConverter>()
.Remove<MarkdownEditorValueConverter>();
// add all known factories, devs can then modify this list on application
// startup either by binding to events or in their own global.asax
composition.WithCollectionBuilder<FilteredControllerFactoryCollectionBuilder>()
composition.FilteredControllerFactory()
.Append<RenderControllerFactory>();
composition.WithCollectionBuilder<UrlProviderCollectionBuilder>()
composition.UrlProviders()
.Append<AliasUrlProvider>()
.Append<DefaultUrlProvider>();
composition.WithCollectionBuilder<MediaUrlProviderCollectionBuilder>()
composition.MediaUrlProviders()
.Append<DefaultMediaUrlProvider>();
composition.RegisterUnique<IContentLastChanceFinder, ContentFinderByConfigured404>();
composition.WithCollectionBuilder<ContentFinderCollectionBuilder>()
composition.ContentFinders()
// all built-in finders in the correct order,
// devs can then modify this list on application startup
.Append<ContentFinderByPageIdQuery>()
@@ -211,7 +207,7 @@ namespace Umbraco.Web.Runtime
composition.RegisterUnique<ICultureDictionaryFactory, DefaultCultureDictionaryFactory>();
// register *all* checks, except those marked [HideFromTypeFinder] of course
composition.WithCollectionBuilder<HealthCheckCollectionBuilder>()
composition.HealthChecks()
.Add(() => composition.TypeLoader.GetTypes<HealthCheck.HealthCheck>());
composition.WithCollectionBuilder<HealthCheckNotificationMethodCollectionBuilder>()
@@ -231,13 +227,13 @@ namespace Umbraco.Web.Runtime
composition.RegisterUnique<IPublishedValueFallback, PublishedValueFallback>();
// register known content apps
composition.WithCollectionBuilder<ContentAppFactoryCollectionBuilder>()
composition.ContentApps()
.Append<ListViewContentAppFactory>()
.Append<ContentEditorContentAppFactory>()
.Append<ContentInfoContentAppFactory>();
// register back office sections in the order we want them rendered
composition.WithCollectionBuilder<SectionCollectionBuilder>()
composition.Sections()
.Append<ContentSection>()
.Append<MediaSection>()
.Append<SettingsSection>()
@@ -248,18 +244,18 @@ namespace Umbraco.Web.Runtime
.Append<TranslationSection>();
// register core CMS dashboards and 3rd party types - will be ordered by weight attribute & merged with package.manifest dashboards
composition.WithCollectionBuilder<DashboardCollectionBuilder>()
composition.Dashboards()
.Add(composition.TypeLoader.GetTypes<IDashboard>());
// register back office trees
// the collection builder only accepts types inheriting from TreeControllerBase
// and will filter out those that are not attributed with TreeAttribute
composition.WithCollectionBuilder<TreeCollectionBuilder>()
composition.Trees()
.AddTreeControllers(umbracoApiControllerTypes.Where(x => typeof(TreeControllerBase).IsAssignableFrom(x)));
// register OEmbed providers - no type scanning - all explicit opt-in of adding types
// note: IEmbedProvider is not IDiscoverable - think about it if going for type scanning
composition.WithCollectionBuilder<EmbedProvidersCollectionBuilder>()
composition.OEmbedProviders()
.Append<YouTube>()
.Append<Instagram>()
.Append<Twitter>()
@@ -274,7 +270,7 @@ namespace Umbraco.Web.Runtime
.Append<Issuu>()
.Append<Hulu>()
.Append<Giphy>();
// replace with web implementation
composition.RegisterUnique<IPublishedSnapshotRebuilder, Migrations.PostMigrations.PublishedSnapshotRebuilder>();