Skip to content

Commit

Permalink
Merge pull request #37 from ProWorksCorporation/v13/main
Browse files Browse the repository at this point in the history
V13/main
  • Loading branch information
protherj authored Apr 3, 2024
2 parents 9a06f94 + c5fe4ea commit cc8fbdc
Show file tree
Hide file tree
Showing 17 changed files with 167 additions and 295 deletions.
4 changes: 4 additions & 0 deletions src/TinyMCE.Umbraco.Premium/Options/TinyMceConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

namespace TinyMCE.Umbraco.Premium.Options
{
/// <summary>
/// Custom configuration model used in the appSettings.config or anywhere the
/// enviroment variables are defined.
/// </summary>
public class TinyMceConfig
{
public string apikey { get; set; } = "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

namespace TinyMCE.Umbraco.Premium.PropertyEditors;

/// <summary>
/// Based on Umbraco-CMS\src\Umbraco.Infrastructure\PropertyEditors\BlockEditorValidatorBase.cs
/// </summary>
internal abstract class TinyBlockEditorValidatorBase : ComplexEditorValidator
{
private readonly IContentTypeService _contentTypeService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ namespace TinyMCE.Umbraco.Premium.PropertyEditors;

/// <summary>
/// Used to deserialize json values and clean up any values based on the existence of element types and layout structure
///
/// Based on Umbraco-CMS\src\Umbraco.Infrastructure\PropertyEditors\BlockEditorValues.cs
/// </summary>
internal class TinyBlockEditorValues
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Blocks;
Expand All @@ -10,58 +11,69 @@

namespace TinyMCE.Umbraco.Premium.PropertyEditors
{
internal abstract class TinyBlockValuePropertyValueEditorBase : DataValueEditor, IDataValueReference, IDataValueTags
/// <summary>
/// Based on Umbraco-CMS\src\Umbraco.Infrastructure\PropertyEditors\BlockValuePropertyValueEditorBase.cs
/// </summary>
internal abstract class TinyBlockValuePropertyValueEditorBase : DataValueEditor, IDataValueReference, IDataValueTags
{
private readonly IDataTypeService _dataTypeService;
private readonly PropertyEditorCollection _propertyEditors;
private readonly ILogger _logger;
private readonly IDataTypeConfigurationCache _dataTypeConfigurationCache;
private readonly PropertyEditorCollection _propertyEditors;
private readonly ILogger _logger;
private readonly DataValueReferenceFactoryCollection _dataValueReferenceFactoryCollection;

protected TinyBlockValuePropertyValueEditorBase(
protected TinyBlockValuePropertyValueEditorBase(
DataEditorAttribute attribute,
PropertyEditorCollection propertyEditors,
IDataTypeService dataTypeService,
ILocalizedTextService textService,
IDataTypeConfigurationCache dataTypeConfigurationCache,
ILocalizedTextService textService,
ILogger logger,
IShortStringHelper shortStringHelper,
IJsonSerializer jsonSerializer,
IIOHelper ioHelper)
IIOHelper ioHelper,
DataValueReferenceFactoryCollection dataValueReferenceFactoryCollection)
: base(textService, shortStringHelper, jsonSerializer, ioHelper, attribute)
{
_propertyEditors = propertyEditors;
_dataTypeService = dataTypeService;
_logger = logger;
}
_propertyEditors = propertyEditors;
_dataTypeConfigurationCache = dataTypeConfigurationCache;
_logger = logger;
_dataValueReferenceFactoryCollection = dataValueReferenceFactoryCollection;
}

/// <inheritdoc />
public abstract IEnumerable<UmbracoEntityReference> GetReferences(object? value);
/// <inheritdoc />
public abstract IEnumerable<UmbracoEntityReference> GetReferences(object? value);

protected IEnumerable<UmbracoEntityReference> GetBlockValueReferences(BlockValue blockValue)
{
var result = new List<UmbracoEntityReference>();

// loop through all content and settings data
foreach (BlockItemData row in blockValue.ContentData.Concat(blockValue.SettingsData))
{
foreach (KeyValuePair<string, BlockItemData.BlockPropertyValue> prop in row.PropertyValues)
{
IDataEditor? propEditor = _propertyEditors[prop.Value.PropertyType.PropertyEditorAlias];

IDataValueEditor? valueEditor = propEditor?.GetValueEditor();
if (!(valueEditor is IDataValueReference reference))
{
continue;
}

var val = prop.Value.Value?.ToString();

IEnumerable<UmbracoEntityReference> refs = reference.GetReferences(val);

result.AddRange(refs);
}
}

return result;
}
var result = new HashSet<UmbracoEntityReference>();
BlockItemData.BlockPropertyValue[] propertyValues = blockValue.ContentData.Concat(blockValue.SettingsData)
.SelectMany(x => x.PropertyValues.Values).ToArray();
foreach (IGrouping<string, object?> valuesByPropertyEditorAlias in propertyValues.GroupBy(x => x.PropertyType.PropertyEditorAlias, x => x.Value))
{
if (!_propertyEditors.TryGet(valuesByPropertyEditorAlias.Key, out IDataEditor? dataEditor))
{
continue;
}

var districtValues = valuesByPropertyEditorAlias.Distinct().ToArray();

if (dataEditor.GetValueEditor() is IDataValueReference reference)
{
foreach (UmbracoEntityReference value in districtValues.SelectMany(reference.GetReferences))
{
result.Add(value);
}
}

IEnumerable<UmbracoEntityReference> references = _dataValueReferenceFactoryCollection.GetReferences(dataEditor, districtValues);

foreach (UmbracoEntityReference value in references)
{
result.Add(value);
}
}

return result;
}

/// <inheritdoc />
public abstract IEnumerable<ITag> GetTags(object? value, object? dataTypeConfiguration, int? languageId);
Expand All @@ -82,9 +94,9 @@ protected IEnumerable<ITag> GetBlockValueTags(BlockValue blockValue, int? langua
continue;
}

object? configuration = _dataTypeService.GetDataType(prop.Value.PropertyType.DataTypeKey)?.Configuration;
object? configuration = _dataTypeConfigurationCache.GetConfiguration(prop.Value.PropertyType.DataTypeKey);

result.AddRange(tagsProvider.GetTags(prop.Value.Value, configuration, languageId));
result.AddRange(tagsProvider.GetTags(prop.Value.Value, configuration, languageId));
}
}

Expand All @@ -105,78 +117,66 @@ protected void MapBlockValueToEditor(IProperty property, BlockValue blockValue)

private void MapBlockItemDataToEditor(IProperty property, List<BlockItemData> items)
{
var valEditors = new Dictionary<int, IDataValueEditor>();

foreach (BlockItemData row in items)
{
foreach (KeyValuePair<string, BlockItemData.BlockPropertyValue> prop in row.PropertyValues)
{
// create a temp property with the value
// - force it to be culture invariant as the block editor can't handle culture variant element properties
prop.Value.PropertyType.Variations = ContentVariation.Nothing;
var tempProp = new Property(prop.Value.PropertyType);
tempProp.SetValue(prop.Value.Value);

IDataEditor? propEditor = _propertyEditors[prop.Value.PropertyType.PropertyEditorAlias];
if (propEditor == null)
{
// NOTE: This logic was borrowed from Nested Content and I'm unsure why it exists.
// if the property editor doesn't exist I think everything will break anyways?
// update the raw value since this is what will get serialized out
row.RawPropertyValues[prop.Key] = tempProp.GetValue()?.ToString();
continue;
}

IDataType? dataType = _dataTypeService.GetDataType(prop.Value.PropertyType.DataTypeId);
if (dataType == null)
{
// deal with weird situations by ignoring them (no comment)
row.PropertyValues.Remove(prop.Key);
_logger.LogWarning(
"ToEditor removed property value {PropertyKey} in row {RowId} for property type {PropertyTypeAlias}",
prop.Key,
row.Key,
property.PropertyType.Alias);
continue;
}

if (!valEditors.TryGetValue(dataType.Id, out IDataValueEditor? valEditor))
{
var tempConfig = dataType.Configuration;
valEditor = propEditor.GetValueEditor(tempConfig);

valEditors.Add(dataType.Id, valEditor);
}

var convValue = valEditor.ToEditor(tempProp);

// update the raw value since this is what will get serialized out
row.RawPropertyValues[prop.Key] = convValue;
}
}
}
var valEditors = new Dictionary<Guid, IDataValueEditor>();

foreach (BlockItemData row in items)
{
foreach (KeyValuePair<string, BlockItemData.BlockPropertyValue> prop in row.PropertyValues)
{
// create a temp property with the value
// - force it to be culture invariant as the block editor can't handle culture variant element properties
prop.Value.PropertyType.Variations = ContentVariation.Nothing;
var tempProp = new Property(prop.Value.PropertyType);
tempProp.SetValue(prop.Value.Value);

IDataEditor? propEditor = _propertyEditors[prop.Value.PropertyType.PropertyEditorAlias];
if (propEditor == null)
{
// NOTE: This logic was borrowed from Nested Content and I'm unsure why it exists.
// if the property editor doesn't exist I think everything will break anyways?
// update the raw value since this is what will get serialized out
row.RawPropertyValues[prop.Key] = tempProp.GetValue()?.ToString();
continue;
}

Guid dataTypeKey = prop.Value.PropertyType.DataTypeKey;
if (!valEditors.TryGetValue(dataTypeKey, out IDataValueEditor? valEditor))
{
var configuration = _dataTypeConfigurationCache.GetConfiguration(dataTypeKey);
valEditor = propEditor.GetValueEditor(configuration);

valEditors.Add(dataTypeKey, valEditor);
}

var convValue = valEditor.ToEditor(tempProp);

// update the raw value since this is what will get serialized out
row.RawPropertyValues[prop.Key] = convValue;
}
}
}

private void MapBlockItemDataFromEditor(List<BlockItemData> items)
{
foreach (BlockItemData row in items)
{
foreach (KeyValuePair<string, BlockItemData.BlockPropertyValue> prop in row.PropertyValues)
{
// Fetch the property types prevalue
var propConfiguration = _dataTypeService.GetDataType(prop.Value.PropertyType.DataTypeId)?.Configuration;
// Fetch the property types prevalue
var configuration = _dataTypeConfigurationCache.GetConfiguration(prop.Value.PropertyType.DataTypeKey);

// Lookup the property editor
IDataEditor? propEditor = _propertyEditors[prop.Value.PropertyType.PropertyEditorAlias];
// Lookup the property editor
IDataEditor? propEditor = _propertyEditors[prop.Value.PropertyType.PropertyEditorAlias];
if (propEditor == null)
{
continue;
}

// Create a fake content property data object
var contentPropData = new ContentPropertyData(prop.Value.Value, propConfiguration);
// Create a fake content property data object
var contentPropData = new ContentPropertyData(prop.Value.Value, configuration);

// Get the property editor to do it's conversion
var newValue = propEditor.GetValueEditor().FromEditor(contentPropData, prop.Value.Value);
// Get the property editor to do it's conversion
var newValue = propEditor.GetValueEditor().FromEditor(contentPropData, prop.Value.Value);

// update the raw value since this is what will get serialized out
row.RawPropertyValues[prop.Key] = newValue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ namespace TinyMCE.Umbraco.Premium.PropertyEditors;

/// <summary>
/// Represents the configuration for the rich text value editor.
///
/// Extends Umbraco-CMS\src\Umbraco.Core\PropertyEditors\RichTextConfiguration.cs
/// </summary>
public class TinyMceUmbracoPremiumConfiguration : RichTextConfiguration
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ namespace TinyMCE.Umbraco.Premium.PropertyEditors;

/// <summary>
/// Represents the configuration editor for the rich text value editor.
///
/// Based on Umbraco-CMS\src\Umbraco.Core\PropertyEditors\RichTextConfigurationEditor.cs
/// </summary>
public class TinyMceUmbracoPremiumConfigurationEditor : ConfigurationEditor<TinyMceUmbracoPremiumConfiguration>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Microsoft.Extensions.Logging;
using System.Diagnostics.CodeAnalysis;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.Media;
Expand All @@ -24,6 +25,9 @@ namespace TinyMCE.Umbraco.Premium.PropertyEditors

/// <summary>
/// Represents the TinyMCE.Umbraco.Premium Rich Text property editor.
///
/// Based on Umbraco-CMS\src\Umbraco.Infrastructure\PropertyEditors\RichTextPropertyEditor.cs
/// with modifications
/// </summary>
[DataEditor(
Constants.PropertyEditors.Aliases.TinyMceUmbracoPremiumRte,
Expand Down Expand Up @@ -185,8 +189,8 @@ internal class TinyMceUmbracoPremiumPropertyValueEditor : TinyBlockValueProperty
public TinyMceUmbracoPremiumPropertyValueEditor(
DataEditorAttribute attribute,
PropertyEditorCollection propertyEditors,
IDataTypeService dataTypeService,
ILogger<TinyMceUmbracoPremiumPropertyValueEditor> logger,
IDataTypeConfigurationCache dataTypeReadCache,
ILogger<TinyMceUmbracoPremiumPropertyValueEditor> logger,
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
ILocalizedTextService localizedTextService,
IShortStringHelper shortStringHelper,
Expand All @@ -198,8 +202,9 @@ public TinyMceUmbracoPremiumPropertyValueEditor(
IHtmlSanitizer htmlSanitizer,
IHtmlMacroParameterParser macroParameterParser,
IContentTypeService contentTypeService,
IPropertyValidationService propertyValidationService)
: base(attribute, propertyEditors, dataTypeService, localizedTextService, logger, shortStringHelper, jsonSerializer, ioHelper)
IPropertyValidationService propertyValidationService,
DataValueReferenceFactoryCollection dataValueReferenceFactoryCollection)
: base(attribute, propertyEditors, dataTypeReadCache, localizedTextService, logger, shortStringHelper, jsonSerializer, ioHelper, dataValueReferenceFactoryCollection)
{
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
_imageSourceParser = imageSourceParser;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ namespace TinyMCE.Umbraco.Premium.PropertyEditors;

/// <summary>
/// Data converter for blocks in the richtext property editor
///
/// Based on Umbraco-CMS\src\Umbraco.Infrastructure\Models\Blocks\RichTextEditorBlockDataConverter.cs
/// </summary>
internal sealed class TinyRichTextEditorBlockDataConverter : BlockEditorDataConverter
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@

namespace TinyMCE.Umbraco.Premium.PropertyEditors;

/// <summary>
/// Based on Umbraco-CMS\src\Umbraco.Infrastructure\PropertyEditors\RichTextEditorBlockValidator.cs
/// </summary>
internal class TinyRichTextEditorBlockValidator : TinyBlockEditorValidatorBase
{
private readonly TinyBlockEditorValues _blockEditorValues;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@

namespace TinyMCE.Umbraco.Premium.PropertyEditors;

/// <summary>
/// Based on Umbraco-CMS\src\Umbraco.Infrastructure\PropertyEditors\RichTextEditorPastedImages.cs
/// </summary>
public sealed class TinyRichTextEditorPastedImages
{
private const string TemporaryImageDataAttribute = "data-tmpimg";
Expand Down
6 changes: 3 additions & 3 deletions src/TinyMCE.Umbraco.Premium/TinyMCE.Umbraco.Premium.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Umbraco.Cms.Core" Version="13.0.0" />
<PackageReference Include="Umbraco.Cms.Web.Website" Version="13.0.0" />
<PackageReference Include="Umbraco.Cms.Web.BackOffice" Version="13.0.0" />
<PackageReference Include="Umbraco.Cms.Core" Version="13.2.2" />
<PackageReference Include="Umbraco.Cms.Web.Website" Version="13.2.2" />
<PackageReference Include="Umbraco.Cms.Web.BackOffice" Version="13.2.2" />
</ItemGroup>

</Project>
Loading

0 comments on commit cc8fbdc

Please sign in to comment.