Skip to content

Commit

Permalink
Merge pull request #367 from leekelleher/dev/v4.x
Browse files Browse the repository at this point in the history
Preparing v4.5.1 release
  • Loading branch information
leekelleher authored Nov 9, 2023
2 parents 4189968 + ea2e7a7 commit 9b2face
Show file tree
Hide file tree
Showing 18 changed files with 436 additions and 235 deletions.
3 changes: 2 additions & 1 deletion .github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ _Let's call those "life's little surprises"._
- When using the **Umbraco Content** data source with an XPath query, inside a Nested Content or Block List editors, it will not be able to identify the contextual containing node ID. e.g. your XPath query will not work. [See #30 for details.](https://github.com/leekelleher/umbraco-contentment/issues/30)
- When using the **Umbraco Content** data source with an XPath query that contains a `$` prefix parameter, the preview will not display the items. [See #120 for details.](https://github.com/leekelleher/umbraco-contentment/issues/120)
- With Umbraco v10 (Contentment v4), **SQL** data source does not support querying SQLite, _(yet!)_ [See #258 for details.](https://github.com/leekelleher/umbraco-contentment/issues/258)

- **.NET Publish with .NET 6 (or newer)**
- When using .NET Publish with .NET 6 (or newer versions of .NET). [See #361 for details](https://github.com/leekelleher/umbraco-contentment/issues/361).

### [Roadmap](ROADMAP.md)

Expand Down
11 changes: 1 addition & 10 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,6 @@ build/assets/
build/build-push-nuget.ps1
build/build-push-umb.ps1
src/packages/*/**
src/Umbraco.Cms.*.x/appsettings-schema.json
src/Umbraco.Cms.*.x/appsettings-schema.Umbraco.Cms.json
src/Umbraco.Cms.*.x/umbraco-package-schema.json
src/Umbraco.Cms.8.x/App_Data/*
src/Umbraco.Cms.*.x/App_Plugins/*/**
src/Umbraco.Cms.8.x/Umbraco/*
src/Umbraco.Cms.*.x/[Uu]mbraco/Data/*
src/Umbraco.Cms.*.x/[Uu]mbraco/Logs/*
src/Umbraco.Cms.*.x/Views/Partials/[Bb]lock[Ll]ist/*
src/Umbraco.Cms.*.x/Views/Partials/[Gg]rid/*
src/Umbraco.Cms.*.x/*
src/Umbraco.Community.Contentment/wwwroot/App_Plugins/Contentment/*
tools/*.exe
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4.5.0
4.5.1
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
{
"key": "Umbraco.Community.Contentment.DataEditors.UmbracoContentDataListSource, Umbraco.Community.Contentment",
"value": {
"parentNode": "umb://document/9772aed63d82474e9269f7f4c5504992"
"parentNode": "umb://document/9772aed63d82474e9269f7f4c5504992",
"sortAlphabetically": "0"
}
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
{
"key": "Umbraco.Community.Contentment.DataEditors.UmbracoContentDataListSource, Umbraco.Community.Contentment",
"value": {
"parentNode": "umb://document/7c6bcf13fa7d4949b975ffb331ee0dcc"
"parentNode": "umb://document/7c6bcf13fa7d4949b975ffb331ee0dcc",
"sortAlphabetically": "1"
}
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
{
"key": "Umbraco.Community.Contentment.DataEditors.UmbracoContentDataListSource, Umbraco.Community.Contentment",
"value": {
"parentNode": "umb://document/9772aed63d82474e9269f7f4c5504992"
"parentNode": "umb://document/9772aed63d82474e9269f7f4c5504992",
"sortAlphabetically": "0"
}
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
{
"key": "Umbraco.Community.Contentment.DataEditors.UmbracoContentDataListSource, Umbraco.Community.Contentment",
"value": {
"parentNode": "umb://document/7c6bcf13fa7d4949b975ffb331ee0dcc"
"parentNode": "umb://document/7c6bcf13fa7d4949b975ffb331ee0dcc",
"sortAlphabetically": "1"
}
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
{
"key": "Umbraco.Community.Contentment.DataEditors.UmbracoContentDataListSource, Umbraco.Community.Contentment",
"value": {
"parentNode": "umb://document/9772aed63d82474e9269f7f4c5504992"
"parentNode": "umb://document/9772aed63d82474e9269f7f4c5504992",
"sortAlphabetically": "0"
}
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
{
"key": "Umbraco.Community.Contentment.DataEditors.UmbracoContentDataListSource, Umbraco.Community.Contentment",
"value": {
"parentNode": "umb://document/7c6bcf13fa7d4949b975ffb331ee0dcc"
"parentNode": "umb://document/7c6bcf13fa7d4949b975ffb331ee0dcc",
"sortAlphabetically": "1"
}
}
],
Expand Down
10 changes: 10 additions & 0 deletions src/Umbraco.Community.Contentment/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,16 @@ internal static partial class PropertyGroups
}
}

internal static partial class Persistance
{
internal static partial class Providers
{
public const string Sqlite = "Microsoft.Data.Sqlite";

public const string SqlServer = "Microsoft.Data.SqlClient";
}
}

internal static partial class Icons
{
public const string Contentment = "icon-contentment";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/* Copyright © 2019 Lee Kelleher.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

/* NOTE: This code file is ONLY for Umbraco v8, .NET Framework 4.7.2.
* For the .NET Core 5.0 version, please see file `SqlDataListSource.NET5_0.cs`. */

#if NET472
using System.Collections.Generic;
using System.Configuration;
using System.Data.Common;
using System.Data.SqlClient;
using System.Data.SqlServerCe;
using System.Linq;
using Microsoft.AspNetCore.Hosting;
using Umbraco.Core;
using Umbraco.Core.IO;
using UmbConstants = Umbraco.Core.Constants;

namespace Umbraco.Community.Contentment.DataEditors
{
public sealed partial class SqlDataListSource : IDataListSource
{
private readonly string _codeEditorMode;
private readonly IEnumerable<DataListItem> _connectionStrings;
private readonly IIOHelper _ioHelper;

public SqlDataListSource(
IWebHostEnvironment webHostEnvironment,
IIOHelper ioHelper)
{
// NOTE: Umbraco doesn't ship with SqlServer mode, so we check if its been added manually, otherwise defaults to Razor.
_codeEditorMode = webHostEnvironment.WebPathExists("~/umbraco/lib/ace-builds/src-min-noconflict/mode-sqlserver.js") == true
? "sqlserver"
: "razor";

_connectionStrings = ConfigurationManager.ConnectionStrings
.Cast<ConnectionStringSettings>()
.Select(x => new DataListItem
{
Name = x.Name,
Value = x.Name
});

_ioHelper = ioHelper;
}

public IEnumerable<DataListItem> GetItems(Dictionary<string, object> config)
{
var items = new List<DataListItem>();

var query = config.GetValueAs("query", string.Empty);
var connectionStringName = config.GetValueAs("connectionString", string.Empty);

if (string.IsNullOrWhiteSpace(query) == true || string.IsNullOrWhiteSpace(connectionStringName) == true)
{
return items;
}

var settings = ConfigurationManager.ConnectionStrings[connectionStringName];
if (settings == null)
{
return items;
}

// NOTE: SQLCE uses a different connection/command. I'm trying to keep this as generic as possible, without resorting to using NPoco. [LK]
if (settings.ProviderName.InvariantEquals(UmbConstants.DatabaseProviders.SqlCe) == true)
{
items.AddRange(GetSqlItems<SqlCeConnection, SqlCeCommand>(query, settings.ConnectionString));
}
else
{
items.AddRange(GetSqlItems<SqlConnection, SqlCommand>(query, settings.ConnectionString));
}

return items;
}

private IEnumerable<DataListItem> GetSqlItems<TConnection, TCommand>(string query, string connectionString)
where TConnection : DbConnection, new()
where TCommand : DbCommand, new()
{
using (var connection = new TConnection() { ConnectionString = connectionString })
using (var command = new TCommand() { Connection = connection, CommandText = query })
{
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read() == true)
{
if (reader.FieldCount > 0)
{
var item = new DataListItem
{
Name = reader[0].TryConvertTo<string>().Result
};

item.Value = reader.FieldCount > 1
? reader[1].TryConvertTo<string>().Result
: item.Name;

if (reader.FieldCount > 2)
item.Description = reader[2].TryConvertTo<string>().Result;

if (reader.FieldCount > 3)
item.Icon = reader[3].TryConvertTo<string>().Result;

if (reader.FieldCount > 4)
item.Disabled = reader[4].ToString().TryConvertTo<bool>().Result;

yield return item;
}
}
}
}
}
}
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/* Copyright © 2019 Lee Kelleher.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

/* NOTE: This code file is ONLY for Umbraco v9, .NET Core 5.0.
* For the .NET Core 6.0 version, please see file `SqlDataListSource.NET6_0.cs`. */

#if NET5_0
using System.Collections.Generic;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Umbraco.Cms.Core.IO;
using Umbraco.Extensions;

namespace Umbraco.Community.Contentment.DataEditors
{
public sealed partial class SqlDataListSource : IDataListSource
{
private readonly string _codeEditorMode;
private readonly IEnumerable<DataListItem> _connectionStrings;
private readonly IIOHelper _ioHelper;
private readonly IConfiguration _configuration;

public SqlDataListSource(
IWebHostEnvironment webHostEnvironment,
IConfiguration configuration,
IIOHelper ioHelper)
{
// NOTE: Umbraco doesn't ship with SqlServer mode, so we check if its been added manually, otherwise defaults to Razor.
_codeEditorMode = webHostEnvironment.WebPathExists("~/umbraco/lib/ace-builds/src-min-noconflict/mode-sqlserver.js") == true
? "sqlserver"
: "razor";

_connectionStrings = configuration
.GetSection("ConnectionStrings")
.GetChildren()
.Where(x => x.Key.InvariantEndsWith("_ProviderName") == false)
.Select(x => new DataListItem
{
Name = x.Key,
Value = x.Key
});

_configuration = configuration;
_ioHelper = ioHelper;
}

public IEnumerable<DataListItem> GetItems(Dictionary<string, object> config)
{
var items = new List<DataListItem>();

var query = config.GetValueAs("query", string.Empty);
var connectionStringName = config.GetValueAs("connectionString", string.Empty);

if (string.IsNullOrWhiteSpace(query) == true || string.IsNullOrWhiteSpace(connectionStringName) == true)
{
return items;
}

var connectionString = _configuration.GetConnectionString(connectionStringName);
if (string.IsNullOrWhiteSpace(connectionString) == true)
{
return items;
}

// TODO: [v9] [LK:2021-05-07] Review SQLCE
// NOTE: SQLCE uses a different connection/command. I'm trying to keep this as generic as possible, without resorting to using NPoco. [LK]
// I've tried digging around Umbraco's `IUmbracoDatabase` layer, but I couldn't get my head around it.
// At the end of the day, if the user has SQLCE configured, it'd be nice for them to query it.
// But I don't want to add an assembly dependency (for SQLCE) to Contentment itself. I'd like to leverage Umbraco's code.

items.AddRange(GetSqlItems<SqlConnection, SqlCommand>(query, connectionString));

return items;
}

private IEnumerable<DataListItem> GetSqlItems<TConnection, TCommand>(string query, string connectionString)
where TConnection : DbConnection, new()
where TCommand : DbCommand, new()
{
using (var connection = new TConnection() { ConnectionString = connectionString })
using (var command = new TCommand() { Connection = connection, CommandText = query })
{
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read() == true)
{
if (reader.FieldCount > 0)
{
var item = new DataListItem
{
Name = reader[0].TryConvertTo<string>().Result
};

item.Value = reader.FieldCount > 1
? reader[1].TryConvertTo<string>().Result
: item.Name;

if (reader.FieldCount > 2)
item.Description = reader[2].TryConvertTo<string>().Result;

if (reader.FieldCount > 3)
item.Icon = reader[3].TryConvertTo<string>().Result;

if (reader.FieldCount > 4)
item.Disabled = reader[4].ToString().TryConvertTo<bool>().Result;

yield return item;
}
}
}
}
}
}
}
#endif
Loading

0 comments on commit 9b2face

Please sign in to comment.