Skip to content
Snippets Groups Projects
Commit 23453ace authored by Andrey Vitushkin's avatar Andrey Vitushkin
Browse files

Issue #3451882: Remove "ipaddress_cidr" field type and rename related classes

parent e4aaae5a
No related branches found
No related tags found
No related merge requests found
Showing with 63 additions and 168 deletions
field.field_settings.ipaddress_pgsql:
type: mapping
label: 'IP address settings'
mapping:
protocol:
type: string
label: 'Protocol'
cidr_format:
type: boolean
label: 'Restrict to cidr format'
field.field_settings.ipaddress_mysql:
type: mapping
label: 'IP address settings'
mapping:
protocol:
type: string
label: 'Protocol'
cidr_format:
type: boolean
label: 'Restrict to cidr format'
# A user can select which "IP Address Functions" to use to display additional # A user can select which "IP Address Functions" to use to display additional
# representations of an IP address. A list of available PostgreSQL functions is # representations of an IP address. A list of available PostgreSQL functions is
# available here: https://www.postgresql.org/docs/current/functions-net.html#FUNCTIONS-NET # available here: https://www.postgresql.org/docs/current/functions-net.html#FUNCTIONS-NET
field.formatter.settings.ipaddress_cidr: field.formatter.settings.ipaddress_pgsql:
type: mapping type: mapping
label: 'Display different representations of an IP address using IP Address Functions' label: 'IP Address function to display additional information about the IP address'
mapping: mapping:
function: function:
type: string type: string
label: 'Function name that applies to the IP address in the formatter' label: 'Function name that applies to the IP address in the formatter'
# The "ipaddress_mysql" field type doesn't use the "IP Address Functions"
# provided by PostgreSQL. It uses the "s1lentium/iptools" PHP library to
# display additional info about the IP address (netmask, network etc.).
field.formatter.settings.ipaddress_mysql:
type: mapping
label: 'Additional information about the IP address'
mapping:
function:
type: string
label: 'Additional information about the IP address that will be shown in the formatter'
field_ipaddress_pgsql:
label: 'IP Address PostgreSQL'
description: 'Stores an IP address using the PostgreSQL Network Address Types.'
weight: -100
...@@ -10,15 +10,14 @@ use Drupal\Core\Routing\RouteMatchInterface; ...@@ -10,15 +10,14 @@ use Drupal\Core\Routing\RouteMatchInterface;
/** /**
* Implements hook_field_info_alter(). * Implements hook_field_info_alter().
* *
* Check if PostgreSQL is being used, and if not, remove field types that use * Check if PostgreSQL is being used, and if not, remove field type that use
* data types provided by PostgreSQL ("Network Address Types"). * data types provided by PostgreSQL ("Network Address Types").
* And vice versa - if PostgreSQL is used, remove the field type that uses the * And vice versa - if PostgreSQL is used, remove the field type that uses the
* INT data type provided by MySQL. * INT data type provided by MySQL.
*/ */
function field_ipaddress_pgsql_field_info_alter(&$info): void { function field_ipaddress_pgsql_field_info_alter(&$info): void {
if (\Drupal::database()->driver() !== 'pgsql') { if (\Drupal::database()->driver() !== 'pgsql') {
unset($info['ipaddress_inet']); unset($info['ipaddress_pgsql']);
unset($info['ipaddress_cidr']);
} }
else { else {
unset($info['ipaddress_mysql']); unset($info['ipaddress_mysql']);
...@@ -27,10 +26,15 @@ function field_ipaddress_pgsql_field_info_alter(&$info): void { ...@@ -27,10 +26,15 @@ function field_ipaddress_pgsql_field_info_alter(&$info): void {
/** /**
* Implements hook_theme(). * Implements hook_theme().
*
* Please pay attention!
* If you name the hook theme as the "field__ipaddress_pgsql", then no variables
* are passed in the template from the "ipaddress_pgsql" formatter.
* It looks like there is some kind of bug related to the names.
*/ */
function field_ipaddress_pgsql_theme($existing, $type, $theme, $path) { function field_ipaddress_pgsql_theme($existing, $type, $theme, $path) {
return [ return [
'field__ipaddress_pgsql' => [ 'field__ipaddress' => [
'variables' => [ 'variables' => [
'value' => NULL, 'value' => NULL,
], ],
......
...@@ -15,37 +15,20 @@ use Drupal\field\FieldStorageConfigInterface; ...@@ -15,37 +15,20 @@ use Drupal\field\FieldStorageConfigInterface;
* Add a custom views exposed filter and a sort plugin. * Add a custom views exposed filter and a sort plugin.
*/ */
function field_ipaddress_pgsql_field_views_data_alter(array &$data, FieldStorageConfigInterface $field) { function field_ipaddress_pgsql_field_views_data_alter(array &$data, FieldStorageConfigInterface $field) {
if ($field->getType() === 'ipaddress_cidr') { if ($field->getType() === 'ipaddress_pgsql') {
$field_name = $field->getName() . '_' . $field->getMainPropertyName(); $field_name = $field->getName() . '_' . $field->getMainPropertyName();
foreach ($data as $table_name => $table_data) { foreach ($data as $table_name => $table_data) {
$help = t('A filter that uses the <a href=":url" target="_blank">IP Address Operators</a> provided by the PostgreSQL.', [':url' => 'https://www.postgresql.org/docs/16/functions-net.html']); $help = t('A filter that uses the <a href=":url" target="_blank">IP Address Operators</a> provided by the PostgreSQL.', [':url' => 'https://www.postgresql.org/docs/16/functions-net.html']);
$data[$table_name][$field_name]['filter'] = [ $data[$table_name][$field_name]['filter'] = [
'title' => t('IP Address PostgreSQL cidr'), 'title' => t('IP Address PostgreSQL'),
'help' => $help, 'help' => $help,
'id' => 'ipaddress_cidr', 'id' => 'ipaddress_pgsql',
]; ];
$data[$table_name][$field_name]['sort'] = [ $data[$table_name][$field_name]['sort'] = [
'id' => 'ipaddress_cidr', 'id' => 'ipaddress_pgsql',
];
}
}
elseif ($field->getType() === 'ipaddress_inet') {
$field_name = $field->getName() . '_' . $field->getMainPropertyName();
foreach ($data as $table_name => $table_data) {
$help = t('A filter that uses the <a href=":url" target="_blank">IP Address Operators</a> provided by the PostgreSQL.', [':url' => 'https://www.postgresql.org/docs/16/functions-net.html']);
$data[$table_name][$field_name]['filter'] = [
'title' => t('IP Address PostgreSQL inet'),
'help' => $help,
'id' => 'ipaddress_inet',
];
$data[$table_name][$field_name]['sort'] = [
'id' => 'ipaddress_inet',
]; ];
} }
} }
......
...@@ -16,7 +16,7 @@ use IPTools\Network; ...@@ -16,7 +16,7 @@ use IPTools\Network;
* id = "ipaddress_mysql", * id = "ipaddress_mysql",
* label = @Translation("Default"), * label = @Translation("Default"),
* field_types = { * field_types = {
* "ipaddress_mysql", * "ipaddress_mysql"
* } * }
* ) * )
*/ */
...@@ -96,7 +96,7 @@ final class IpAddressMySqlFormatter extends FormatterBase { ...@@ -96,7 +96,7 @@ final class IpAddressMySqlFormatter extends FormatterBase {
if ($this->getSetting('function') === '') { if ($this->getSetting('function') === '') {
$prefixLength = Network::parse("$ipAddress $networkMask")->getPrefixLength(); $prefixLength = Network::parse("$ipAddress $networkMask")->getPrefixLength();
return [ return [
'#theme' => 'field__ipaddress_pgsql', '#theme' => 'field__ipaddress',
'#value' => "$ipAddress/$prefixLength", '#value' => "$ipAddress/$prefixLength",
]; ];
} }
...@@ -127,7 +127,7 @@ final class IpAddressMySqlFormatter extends FormatterBase { ...@@ -127,7 +127,7 @@ final class IpAddressMySqlFormatter extends FormatterBase {
} }
return [ return [
'#theme' => 'field__ipaddress_pgsql', '#theme' => 'field__ipaddress',
'#value' => $value, '#value' => $value,
]; ];
......
<?php
declare(strict_types=1);
namespace Drupal\field_ipaddress_pgsql\Plugin\Field\FieldType;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\TypedData\DataDefinition;
/**
* Plugin implementation of the 'IP Address PostgreSQL cidr' field type.
*
* @FieldType(
* id = "ipaddress_cidr",
* label = @Translation("cidr"),
* description = @Translation("Stores an IP address using the PostgreSQL cidr data type."),
* category = "field_ipaddress_pgsql",
* weight = -30,
* default_widget = "ipaddress_pgsql",
* default_formatter = "ipaddress_cidr",
* constraints = {"CidrFormat" = {}}
* )
*/
final class IpAddressCidrField extends FieldItemBase {
/**
* {@inheritdoc}
*/
public static function defaultStorageSettings(): array {
return [] + parent::defaultStorageSettings();
}
/**
* {@inheritdoc}
*/
public function isEmpty(): bool {
return match ($this->get('value')->getValue()) {
NULL, '' => TRUE,
default => FALSE,
};
}
/**
* {@inheritdoc}
*/
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition): array {
$properties = [];
$properties['value'] = DataDefinition::create('any')
->setLabel(t('Value'));
return $properties;
}
/**
* {@inheritdoc}
*/
public static function schema(FieldStorageDefinitionInterface $field_definition): array {
$columns = [
'value' => [
'type' => 'text',
'pgsql_type' => 'cidr',
'not null' => TRUE,
'description' => 'The IP address stored as the PostgreSQL cidr type.',
],
];
// Adding the GIST index failed, the hack that is suggested here
// https://www.drupal.org/node/3264989 didn't work.
// Also, there is an open issue:
// https://www.drupal.org/project/drupal/issues/3397622
$indexes = [
'value' => [
'value',
],
];
$schema = [
'columns' => $columns,
'indexes' => $indexes,
];
return $schema;
}
/**
* {@inheritdoc}
*/
public static function generateSampleValue(FieldDefinitionInterface $field_definition): array {
$values['value'] = '192.168.100.128/25';
return $values;
}
}
...@@ -10,20 +10,19 @@ use Drupal\Core\Field\FieldStorageDefinitionInterface; ...@@ -10,20 +10,19 @@ use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\TypedData\DataDefinition; use Drupal\Core\TypedData\DataDefinition;
/** /**
* Plugin implementation of the 'IP Address PostgreSQL inet' field type. * Plugin implementation of the 'IP Address PostgreSQL' field type.
* *
* @FieldType( * @FieldType(
* id = "ipaddress_inet", * id = "ipaddress_pgsql",
* label = @Translation("inet"), * label = @Translation("IP address"),
* description = @Translation("Stores an IP address using the PostgreSQL inet data type."), * description = @Translation("Stores an IP address."),
* category = "field_ipaddress_pgsql",
* weight = -100, * weight = -100,
* default_widget = "ipaddress_pgsql", * default_widget = "ipaddress_pgsql",
* default_formatter = "ipaddress_inet", * default_formatter = "ipaddress_pgsql",
* constraints = {"InetFormat" = {}} * constraints = {"PostgreSqlFormat" = {}}
* ) * )
*/ */
final class IpAddressInetField extends FieldItemBase { final class IpAddressPostgreSqlField extends FieldItemBase {
/** /**
* {@inheritdoc} * {@inheritdoc}
...@@ -57,12 +56,14 @@ final class IpAddressInetField extends FieldItemBase { ...@@ -57,12 +56,14 @@ final class IpAddressInetField extends FieldItemBase {
* {@inheritdoc} * {@inheritdoc}
*/ */
public static function schema(FieldStorageDefinitionInterface $field_definition): array { public static function schema(FieldStorageDefinitionInterface $field_definition): array {
// We add the "type" key just to prevent error messages like "Warning:
// Undefined array key "type" in views_field_default_views_data()..."
$columns = [ $columns = [
'value' => [ 'value' => [
'type' => 'text',
'pgsql_type' => 'inet', 'pgsql_type' => 'inet',
'not null' => TRUE, 'not null' => TRUE,
'description' => 'The IP address stored as the PostgreSQL inet type.', 'description' => 'The IP address.',
'type' => '',
], ],
]; ];
......
...@@ -61,7 +61,7 @@ final class IpAddressMySqlWidget extends WidgetBase { ...@@ -61,7 +61,7 @@ final class IpAddressMySqlWidget extends WidgetBase {
$item['network_mask'] = inet_pton($networkMask); $item['network_mask'] = inet_pton($networkMask);
} }
catch (\Exception $e) { catch (\Exception $e) {
// Set some values, because if the values are empty, then he validate() // Set some values, because if the values are empty, then the validate()
// method of the MySqlFormatConstraintValidator class is not called and // method of the MySqlFormatConstraintValidator class is not called and
// the validation does not occur. We do this to avoid adding an element // the validation does not occur. We do this to avoid adding an element
// validator handler in the formElement() methods. // validator handler in the formElement() methods.
......
...@@ -19,8 +19,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; ...@@ -19,8 +19,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
* id = "ipaddress_pgsql", * id = "ipaddress_pgsql",
* label = @Translation("IP Address PostgreSQL"), * label = @Translation("IP Address PostgreSQL"),
* field_types = { * field_types = {
* "ipaddress_inet", * "ipaddress_pgsql"
* "ipaddress_cidr"
* } * }
* ) * )
*/ */
......
<?php
declare(strict_types=1);
namespace Drupal\field_ipaddress_pgsql\Plugin\Validation\Constraint;
use Symfony\Component\Validator\Constraint;
/**
* Provides a cidr format validation constraint.
*
* @Constraint(
* id = "CidrFormat",
* label = @Translation("cidr format validation", context = "Validation"),
* )
*/
final class CidrFormatConstraint extends Constraint {
/**
* Message for when the value isn't in the proper format.
*
* @var string
*/
public string $message = 'The value is in the wrong format for the cidr type. See <a href="https://www.postgresql.org/docs/current/datatype-net-types.html#DATATYPE-NET-CIDR-TABLE" target="_blank">the cidr Type Input Examples</a>.';
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment