Merge remote-tracking branch 'origin/v8/dev' into netcore/dev

# Conflicts:
#	src/Umbraco.Infrastructure/PropertyEditors/DataValueReferenceFactoryCollection.cs
#	src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs
#	src/Umbraco.Web/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs
This commit is contained in:
Bjarke Berg
2020-02-25 11:18:35 +01:00
18 changed files with 432 additions and 46 deletions

View File

@@ -27,6 +27,13 @@ namespace Umbraco.Core.Persistence.Repositories
/// <returns></returns>
bool HasContainerInPath(string contentPath);
/// <summary>
/// Gets a value indicating whether there is a list view content item in the path.
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
bool HasContainerInPath(params int[] ids);
/// <summary>
/// Returns true or false depending on whether content nodes have been created based on the provided content type id.
/// </summary>

View File

@@ -1312,14 +1312,16 @@ WHERE cmsContentType." + aliasColumn + @" LIKE @pattern",
return test;
}
/// <summary>
/// Given the path of a content item, this will return true if the content item exists underneath a list view content item
/// </summary>
/// <param name="contentPath"></param>
/// <returns></returns>
/// <inheritdoc />
public bool HasContainerInPath(string contentPath)
{
var ids = contentPath.Split(',').Select(int.Parse);
var ids = contentPath.Split(',').Select(int.Parse).ToArray();
return HasContainerInPath(ids);
}
/// <inheritdoc />
public bool HasContainerInPath(params int[] ids)
{
var sql = new Sql($@"SELECT COUNT(*) FROM cmsContentType
INNER JOIN {Constants.DatabaseSchema.Tables.Content} ON cmsContentType.nodeId={Constants.DatabaseSchema.Tables.Content}.contentTypeId
WHERE {Constants.DatabaseSchema.Tables.Content}.nodeId IN (@ids) AND cmsContentType.isContainer=@isContainer", new { ids, isContainer = true });

View File

@@ -16,35 +16,46 @@ namespace Umbraco.Core.PropertyEditors
public IEnumerable<UmbracoEntityReference> GetAllReferences(IPropertyCollection properties, PropertyEditorCollection propertyEditors)
{
var trackedRelations = new List<UmbracoEntityReference>();
var trackedRelations = new HashSet<UmbracoEntityReference>();
foreach (var p in properties)
{
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
//TODO: We will need to change this once we support tracking via variants/segments
// for now, we are tracking values from ALL variants
var valueEditor = editor.GetValueEditor();
if (valueEditor is IDataValueReference reference)
foreach(var propertyVal in p.Values)
{
var refs = reference.GetReferences(val);
trackedRelations.AddRange(refs);
var val = propertyVal.EditedValue;
var valueEditor = editor.GetValueEditor();
if (valueEditor is IDataValueReference reference)
{
var refs = reference.GetReferences(val);
foreach(var r in refs)
trackedRelations.Add(r);
}
// 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));
// 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))
{
foreach(var r in item.GetDataValueReference().GetReferences(val))
trackedRelations.Add(r);
}
}
}
}
return trackedRelations;

View File

@@ -1,12 +1,23 @@
using System;
using HeyRed.MarkdownSharp;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Strings;
using Umbraco.Web.Templates;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
public class MarkdownEditorValueConverter : PropertyValueConverterBase
{
private readonly HtmlLocalLinkParser _localLinkParser;
private readonly HtmlUrlParser _urlParser;
public MarkdownEditorValueConverter(HtmlLocalLinkParser localLinkParser, HtmlUrlParser urlParser)
{
_localLinkParser = localLinkParser;
_urlParser = urlParser;
}
public override bool IsConverter(IPublishedPropertyType propertyType)
=> Constants.PropertyEditors.Aliases.MarkdownEditor.Equals(propertyType.EditorAlias);
@@ -15,20 +26,26 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
// PropertyCacheLevel.Content is ok here because that converter does not parse {locallink} nor executes macros
public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType)
=> PropertyCacheLevel.Element;
=> PropertyCacheLevel.Snapshot;
public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview)
{
// in xml a string is: string
// in the database a string is: string
// default value is: null
return source;
if (source == null) return null;
var sourceString = source.ToString();
// ensures string is parsed for {localLink} and urls are resolved correctly
sourceString = _localLinkParser.EnsureInternalLinks(sourceString, preview);
sourceString = _urlParser.EnsureUrls(sourceString);
return sourceString;
}
public override object ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
{
// convert markup to HTML for frontend rendering.
// source should come from ConvertSource and be a string (or null) already
return new HtmlEncodedString(inter == null ? string.Empty : (string) inter);
var mark = new Markdown();
return new HtmlEncodedString(inter == null ? string.Empty : mark.Transform((string)inter));
}
public override object ConvertIntermediateToXPath(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)

View File

@@ -318,6 +318,15 @@ namespace Umbraco.Core.Services.Implement
}
}
public bool HasContainerInPath(params int[] ids)
{
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
{
// can use same repo for both content and media
return Repository.HasContainerInPath(ids);
}
}
public IEnumerable<TItem> GetDescendants(int id, bool andSelf)
{
using (var scope = ScopeProvider.CreateScope(autoComplete: true))