Moves the grid configuration to a config class so it can be re-used. Updates the BackOfficeController to use the new config classes. Creates a new Grid property value converter (which can be overridden by user's ones) which merges the grid config values at runtime so we are not storing stale grid config values with the actual property value. Now we need to ensure that the grid doesn't post or persist these config values since they don't belong there.
This commit is contained in:
16
src/Umbraco.Core/Configuration/Grid/GridConfig.cs
Normal file
16
src/Umbraco.Core/Configuration/Grid/GridConfig.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.IO;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.Configuration.Grid
|
||||
{
|
||||
class GridConfig : IGridConfig
|
||||
{
|
||||
public GridConfig(ILogger logger, IRuntimeCacheProvider runtimeCache, DirectoryInfo appPlugins, DirectoryInfo configFolder, bool isDebug)
|
||||
{
|
||||
EditorsConfig = new GridEditorsConfig(logger, runtimeCache, appPlugins, configFolder, isDebug);
|
||||
}
|
||||
|
||||
public IGridEditorsConfig EditorsConfig { get; private set; }
|
||||
}
|
||||
}
|
||||
78
src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs
Normal file
78
src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Manifest;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Core.Configuration.Grid
|
||||
{
|
||||
class GridEditorsConfig : IGridEditorsConfig
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IRuntimeCacheProvider _runtimeCache;
|
||||
private readonly DirectoryInfo _appPlugins;
|
||||
private readonly DirectoryInfo _configFolder;
|
||||
private readonly bool _isDebug;
|
||||
|
||||
public GridEditorsConfig(ILogger logger, IRuntimeCacheProvider runtimeCache, DirectoryInfo appPlugins, DirectoryInfo configFolder, bool isDebug)
|
||||
{
|
||||
_logger = logger;
|
||||
_runtimeCache = runtimeCache;
|
||||
_appPlugins = appPlugins;
|
||||
_configFolder = configFolder;
|
||||
_isDebug = isDebug;
|
||||
}
|
||||
|
||||
public IEnumerable<IGridEditorConfig> Editors
|
||||
{
|
||||
get
|
||||
{
|
||||
Func<List<GridEditor>> getResult = () =>
|
||||
{
|
||||
var editors = new List<GridEditor>();
|
||||
var gridConfig = Path.Combine(_configFolder.FullName, "grid.editors.config.js");
|
||||
if (File.Exists(gridConfig))
|
||||
{
|
||||
try
|
||||
{
|
||||
var arr = JArray.Parse(File.ReadAllText(gridConfig));
|
||||
//ensure the contents parse correctly to objects
|
||||
var parsed = ManifestParser.GetGridEditors(arr);
|
||||
editors.AddRange(parsed);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error<GridEditorsConfig>("Could not parse the contents of grid.editors.config.js into a JSON array", ex);
|
||||
}
|
||||
}
|
||||
|
||||
var parser = new ManifestParser(_appPlugins, _runtimeCache);
|
||||
var builder = new ManifestBuilder(_runtimeCache, parser);
|
||||
foreach (var gridEditor in builder.GridEditors)
|
||||
{
|
||||
//no duplicates! (based on alias)
|
||||
if (editors.Contains(gridEditor) == false)
|
||||
{
|
||||
editors.Add(gridEditor);
|
||||
}
|
||||
}
|
||||
return editors;
|
||||
};
|
||||
|
||||
//cache the result if debugging is disabled
|
||||
var result = _isDebug
|
||||
? getResult()
|
||||
: _runtimeCache.GetCacheItem<List<GridEditor>>(
|
||||
typeof(GridEditorsConfig) + "Editors",
|
||||
() => getResult(),
|
||||
TimeSpan.FromMinutes(10));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
14
src/Umbraco.Core/Configuration/Grid/IGridConfig.cs
Normal file
14
src/Umbraco.Core/Configuration/Grid/IGridConfig.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Umbraco.Core.Configuration.Grid
|
||||
{
|
||||
public interface IGridConfig
|
||||
{
|
||||
|
||||
IGridEditorsConfig EditorsConfig { get; }
|
||||
|
||||
}
|
||||
}
|
||||
14
src/Umbraco.Core/Configuration/Grid/IGridEditorConfig.cs
Normal file
14
src/Umbraco.Core/Configuration/Grid/IGridEditorConfig.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Umbraco.Core.Configuration.Grid
|
||||
{
|
||||
public interface IGridEditorConfig
|
||||
{
|
||||
string Name { get; }
|
||||
string Alias { get; }
|
||||
string View { get; }
|
||||
string Render { get; }
|
||||
IDictionary<string, object> Config { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Configuration.Grid
|
||||
{
|
||||
public interface IGridEditorsConfig
|
||||
{
|
||||
IEnumerable<IGridEditorConfig> Editors { get; }
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,13 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Configuration.BaseRest;
|
||||
using Umbraco.Core.Configuration.Dashboard;
|
||||
using Umbraco.Core.Configuration.Grid;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
@@ -67,6 +70,7 @@ namespace Umbraco.Core.Configuration
|
||||
private IDashboardSection _dashboardSection;
|
||||
private IUmbracoSettingsSection _umbracoSettings;
|
||||
private IBaseRestSection _baseRestExtensions;
|
||||
private IGridConfig _gridConfig;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the IDashboardSection
|
||||
@@ -140,6 +144,28 @@ namespace Umbraco.Core.Configuration
|
||||
return _baseRestExtensions;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Only for testing
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void SetGridConfig(IGridConfig value)
|
||||
{
|
||||
_gridConfig = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the IGridConfig
|
||||
/// </summary>
|
||||
public IGridConfig GridConfig(ILogger logger, IRuntimeCacheProvider runtimeCache, DirectoryInfo appPlugins, DirectoryInfo configFolder, bool isDebug)
|
||||
{
|
||||
if (_gridConfig == null)
|
||||
{
|
||||
_gridConfig = new GridConfig(logger, runtimeCache, appPlugins, configFolder, isDebug);
|
||||
}
|
||||
|
||||
return _gridConfig;
|
||||
}
|
||||
|
||||
//TODO: Add other configurations here !
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core.Configuration.Grid;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
internal class GridEditor
|
||||
internal class GridEditor : IGridEditorConfig
|
||||
{
|
||||
public GridEditor()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.Grid;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
{
|
||||
[DefaultPropertyValueConverter(typeof(JsonValueConverter))] //this shadows the JsonValueConverter
|
||||
[PropertyValueType(typeof(JToken))]
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
|
||||
public class GridValueConverter : JsonValueConverter
|
||||
{
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
{
|
||||
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.GridAlias);
|
||||
}
|
||||
|
||||
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
if (source == null) return null;
|
||||
var sourceString = source.ToString();
|
||||
|
||||
if (sourceString.DetectIsJson())
|
||||
{
|
||||
try
|
||||
{
|
||||
var obj = JsonConvert.DeserializeObject<JObject>(sourceString);
|
||||
|
||||
//so we have the grid json... we need to merge in the grid's configuration values with the values
|
||||
// we've saved in the database so that when the front end gets this value, it is up-to-date.
|
||||
|
||||
//TODO: Change all singleton access to use ctor injection in v8!!!
|
||||
//TODO: That would mean that property value converters would need to be request lifespan, hrm....
|
||||
var gridConfig = UmbracoConfig.For.GridConfig(
|
||||
ApplicationContext.Current.ProfilingLogger.Logger,
|
||||
ApplicationContext.Current.ApplicationCache.RuntimeCache,
|
||||
new DirectoryInfo(HttpContext.Current.Server.MapPath(SystemDirectories.AppPlugins)),
|
||||
new DirectoryInfo(HttpContext.Current.Server.MapPath(SystemDirectories.Config)),
|
||||
HttpContext.Current.IsDebuggingEnabled);
|
||||
|
||||
var sections = GetArray(obj, "sections");
|
||||
foreach (var section in sections.Cast<JObject>())
|
||||
{
|
||||
var rows = GetArray(section, "rows");
|
||||
foreach (var row in rows.Cast<JObject>())
|
||||
{
|
||||
var areas = GetArray(row, "areas");
|
||||
foreach (var area in areas.Cast<JObject>())
|
||||
{
|
||||
var controls = GetArray(area, "controls");
|
||||
foreach (var control in controls.Cast<JObject>())
|
||||
{
|
||||
var editor = control.Value<JObject>("editor");
|
||||
if (editor != null)
|
||||
{
|
||||
var alias = editor.Value<string>("alias");
|
||||
if (alias.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
//find the alias in config
|
||||
var found = gridConfig.EditorsConfig.Editors.FirstOrDefault(x => x.Alias == alias);
|
||||
if (found != null)
|
||||
{
|
||||
//add/replace the editor value with the one from config
|
||||
|
||||
var serialized = new JObject();
|
||||
serialized["name"] = found.Name;
|
||||
serialized["alias"] = found.Alias;
|
||||
serialized["view"] = found.View;
|
||||
serialized["render"] = found.Render;
|
||||
serialized["config"] = JObject.FromObject(found.Config);
|
||||
|
||||
control["editor"] = serialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.Error<JsonValueConverter>("Could not parse the string " + sourceString + " to a json object", ex);
|
||||
}
|
||||
}
|
||||
|
||||
//it's not json, just return the string
|
||||
return sourceString;
|
||||
}
|
||||
|
||||
private JArray GetArray(JObject obj, string propertyName)
|
||||
{
|
||||
JToken token;
|
||||
if (obj.TryGetValue(propertyName, out token))
|
||||
{
|
||||
var asArray = token as JArray;
|
||||
return asArray ?? new JArray();
|
||||
}
|
||||
return new JArray();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -204,6 +204,11 @@
|
||||
<Compile Include="Configuration\FileSystemProviderElement.cs" />
|
||||
<Compile Include="Configuration\FileSystemProviderElementCollection.cs" />
|
||||
<Compile Include="Configuration\FileSystemProvidersSection.cs" />
|
||||
<Compile Include="Configuration\Grid\GridConfig.cs" />
|
||||
<Compile Include="Configuration\Grid\GridEditorsConfig.cs" />
|
||||
<Compile Include="Configuration\Grid\IGridConfig.cs" />
|
||||
<Compile Include="Configuration\Grid\IGridEditorConfig.cs" />
|
||||
<Compile Include="Configuration\Grid\IGridEditorsConfig.cs" />
|
||||
<Compile Include="Configuration\UmbracoConfig.cs" />
|
||||
<Compile Include="Configuration\UmbracoConfigurationSection.cs" />
|
||||
<Compile Include="Configuration\UmbracoSettings\AppCodeFileExtensionsCollection.cs" />
|
||||
@@ -403,6 +408,7 @@
|
||||
<Compile Include="Persistence\Repositories\RepositoryCacheOptions.cs" />
|
||||
<Compile Include="Persistence\Repositories\TaskRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\TaskTypeRepository.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\GridValueConverter.cs" />
|
||||
<Compile Include="Security\BackOfficeClaimsIdentityFactory.cs" />
|
||||
<Compile Include="Security\BackOfficeUserManager.cs" />
|
||||
<Compile Include="Security\BackOfficeUserStore.cs" />
|
||||
|
||||
@@ -163,48 +163,14 @@ namespace Umbraco.Web.Editors
|
||||
[HttpGet]
|
||||
public JsonNetResult GetGridConfig()
|
||||
{
|
||||
Func<List<GridEditor>> getResult = () =>
|
||||
{
|
||||
var editors = new List<GridEditor>();
|
||||
var gridConfig = Server.MapPath("~/Config/grid.editors.config.js");
|
||||
if (System.IO.File.Exists(gridConfig))
|
||||
{
|
||||
try
|
||||
{
|
||||
var arr = JArray.Parse(System.IO.File.ReadAllText(gridConfig));
|
||||
//ensure the contents parse correctly to objects
|
||||
var parsed = ManifestParser.GetGridEditors(arr);
|
||||
editors.AddRange(parsed);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.Error<BackOfficeController>("Could not parse the contents of grid.editors.config.js into a JSON array", ex);
|
||||
}
|
||||
}
|
||||
var gridConfig = UmbracoConfig.For.GridConfig(
|
||||
Logger,
|
||||
ApplicationContext.ApplicationCache.RuntimeCache,
|
||||
new DirectoryInfo(Server.MapPath(SystemDirectories.AppPlugins)),
|
||||
new DirectoryInfo(Server.MapPath(SystemDirectories.Config)),
|
||||
HttpContext.IsDebuggingEnabled);
|
||||
|
||||
var plugins = new DirectoryInfo(Server.MapPath("~/App_Plugins"));
|
||||
var parser = new ManifestParser(plugins, ApplicationContext.ApplicationCache.RuntimeCache);
|
||||
var builder = new ManifestBuilder(ApplicationContext.ApplicationCache.RuntimeCache, parser);
|
||||
foreach (var gridEditor in builder.GridEditors)
|
||||
{
|
||||
//no duplicates! (based on alias)
|
||||
if (editors.Contains(gridEditor) == false)
|
||||
{
|
||||
editors.Add(gridEditor);
|
||||
}
|
||||
}
|
||||
return editors;
|
||||
};
|
||||
|
||||
//cache the result if debugging is disabled
|
||||
var result = HttpContext.IsDebuggingEnabled
|
||||
? getResult()
|
||||
: ApplicationContext.ApplicationCache.RuntimeCache.GetCacheItem<List<GridEditor>>(
|
||||
typeof(BackOfficeController) + "GetGridConfig",
|
||||
() => getResult(),
|
||||
new TimeSpan(0, 10, 0));
|
||||
|
||||
return new JsonNetResult { Data = result, Formatting = Formatting.Indented };
|
||||
return new JsonNetResult { Data = gridConfig.EditorsConfig.Editors, Formatting = Formatting.Indented };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Umbraco.Web
|
||||
public static MvcHtmlString GetGridHtml(this HtmlHelper html, IPublishedProperty property, string framework = "bootstrap3")
|
||||
{
|
||||
var asString = property.Value as string;
|
||||
if (asString.IsNullOrWhiteSpace()) return new MvcHtmlString(string.Empty);
|
||||
if (asString != null && string.IsNullOrEmpty(asString)) return new MvcHtmlString(string.Empty);
|
||||
|
||||
var view = "Grid/" + framework;
|
||||
return html.Partial(view, property.Value);
|
||||
@@ -56,7 +56,7 @@ namespace Umbraco.Web
|
||||
public static MvcHtmlString GetGridHtml(this IPublishedProperty property, HtmlHelper html, string framework = "bootstrap3")
|
||||
{
|
||||
var asString = property.Value as string;
|
||||
if (asString.IsNullOrWhiteSpace()) return new MvcHtmlString(string.Empty);
|
||||
if (asString != null && string.IsNullOrEmpty(asString)) return new MvcHtmlString(string.Empty);
|
||||
|
||||
var view = "Grid/" + framework;
|
||||
return html.Partial(view, property.Value);
|
||||
@@ -91,7 +91,7 @@ namespace Umbraco.Web
|
||||
public static MvcHtmlString GetGridHtml(this IPublishedProperty property, string framework = "bootstrap3")
|
||||
{
|
||||
var asString = property.Value as string;
|
||||
if (asString.IsNullOrWhiteSpace()) return new MvcHtmlString(string.Empty);
|
||||
if (asString != null && string.IsNullOrEmpty(asString)) return new MvcHtmlString(string.Empty);
|
||||
|
||||
var htmlHelper = CreateHtmlHelper(property.Value);
|
||||
return htmlHelper.GetGridHtml(property, framework);
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.Error<JsonValueConverter>("Could not parse the string " + sourceString + " to a json object", ex);
|
||||
LogHelper.Error<RelatedLinksEditorValueConvertor>("Could not parse the string " + sourceString + " to a json object", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.Error<JsonValueConverter>("Could not parse the string " + sourceString + " to a json object", ex);
|
||||
LogHelper.Error<RelatedLinksEditorValueConvertor>("Could not parse the string " + sourceString + " to a json object", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user