Skip to content
Snippets Groups Projects
Commit e30e80c5 authored by Alex Pott's avatar Alex Pott
Browse files

Issue #2015691 by plopesc, swentel: Convert field type to typed data plugin for number module.

parent 57dc8767
No related branches found
No related tags found
2 merge requests!7452Issue #1797438. HTML5 validation is preventing form submit and not fully...,!789Issue #3210310: Adjust Database API to remove deprecated Drupal 9 code in Drupal 10
<?php
/**
* @file
* Contains \Drupal\number\Plugin\field\field_type\DecimalItem.
*/
namespace Drupal\number\Plugin\field\field_type;
use Drupal\Core\Entity\Annotation\FieldType;
use Drupal\Core\Annotation\Translation;
use Drupal\field\Plugin\Core\Entity\Field;
use Drupal\Component\Utility\MapArray;
/**
* Plugin implementation of the 'number_decimal' field type.
*
* @FieldType(
* id = "number_decimal",
* module = "number",
* label = @Translation("Decimal"),
* description = @Translation("This field stores a number in the database in a fixed decimal format."),
* settings = {
* "precision" = "10",
* "scale" = "2"
* },
* instance_settings = {
* "min" = "",
* "max" = "",
* "prefix" = "",
* "suffix" = ""
* },
* default_widget = "number",
* default_formatter = "number_decimal"
* )
*/
class DecimalItem extends NumberItemBase {
/**
* {@inheritdoc}
*/
public function getPropertyDefinitions() {
if (!isset(static::$propertyDefinitions)) {
static::$propertyDefinitions['value'] = array(
'type' => 'string',
'label' => t('Decimal value'),
);
}
return static::$propertyDefinitions;
}
/**
* {@inheritdoc}
*/
public static function schema(Field $field) {
return array(
'columns' => array(
'value' => array(
'type' => 'numeric',
'precision' => $field->settings['precision'],
'scale' => $field->settings['scale'],
'not null' => FALSE
)
),
);
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, array &$form_state) {
$element = array();
$settings = $this->getFieldDefinition()->getFieldSettings();
$has_data = $this->getInstance()->getField()->hasData();
$element['precision'] = array(
'#type' => 'select',
'#title' => t('Precision'),
'#options' => MapArray::copyValuesToKeys(range(10, 32)),
'#default_value' => $settings['precision'],
'#description' => t('The total number of digits to store in the database, including those to the right of the decimal.'),
'#disabled' => $has_data,
);
$element['scale'] = array(
'#type' => 'select',
'#title' => t('Scale'),
'#options' => MapArray::copyValuesToKeys(range(0, 10)),
'#default_value' => $settings['scale'],
'#description' => t('The number of digits to the right of the decimal.'),
'#disabled' => $has_data,
);
return $element;
}
/**
* {@inheritdoc}
*/
public function preSave() {
$this->value = round($this->value, $this->getFieldDefinition()->getFieldSetting('scale'));
}
}
<?php
/**
* @file
* Contains \Drupal\number\Plugin\field\field_type\FloatItem.
*/
namespace Drupal\number\Plugin\field\field_type;
use Drupal\Core\Entity\Annotation\FieldType;
use Drupal\Core\Annotation\Translation;
use Drupal\field\Plugin\Core\Entity\Field;
/**
* Plugin implementation of the 'number_float' field type.
*
* @FieldType(
* id = "number_float",
* module = "number",
* label = @Translation("Float"),
* description = @Translation("This field stores a number in the database in a floating point format."),
* instance_settings = {
* "min" = "",
* "max" = "",
* "prefix" = "",
* "suffix" = ""
* },
* default_widget = "number",
* default_formatter = "number_decimal"
* )
*/
class FloatItem extends NumberItemBase {
/**
* {@inheritdoc}
*/
public function getPropertyDefinitions() {
if (!isset(static::$propertyDefinitions)) {
static::$propertyDefinitions['value'] = array(
'type' => 'float',
'label' => t('float value'),
);
}
return static::$propertyDefinitions;
}
/**
* {@inheritdoc}
*/
public static function schema(Field $field) {
return array(
'columns' => array(
'value' => array(
'type' => 'float',
'not null' => FALSE,
),
),
);
}
}
<?php
/**
* @file
* Contains \Drupal\number\Plugin\field\field_type\IntegerItem.
*/
namespace Drupal\number\Plugin\field\field_type;
use Drupal\Core\Entity\Annotation\FieldType;
use Drupal\Core\Annotation\Translation;
use Drupal\field\Plugin\Core\Entity\Field;
/**
* Plugin implementation of the 'number_integer' field type.
*
* @FieldType(
* id = "number_integer",
* module = "number",
* label = @Translation("Integer"),
* description = @Translation("This field stores a number in the database as an integer."),
* instance_settings = {
* "min" = "",
* "max" = "",
* "prefix" = "",
* "suffix" = ""
* },
* default_widget = "number",
* default_formatter = "number_integer"
* )
*/
class IntegerItem extends NumberItemBase {
/**
* {@inheritdoc}
*/
public function getPropertyDefinitions() {
if (!isset(static::$propertyDefinitions)) {
static::$propertyDefinitions['value'] = array(
'type' => 'integer',
'label' => t('Integer value'),
);
}
return static::$propertyDefinitions;
}
/**
* {@inheritdoc}
*/
public static function schema(Field $field) {
return array(
'columns' => array(
'value' => array(
'type' => 'int',
'not null' => FALSE,
),
),
);
}
}
<?php
/**
* @file
* Contains \Drupal\number\Plugin\field\field_type\NumberItemBase.
*/
namespace Drupal\number\Plugin\field\field_type;
use Drupal\field\Plugin\Type\FieldType\ConfigFieldItemBase;
/**
* Base class for 'number' configurable field types.
*/
abstract class NumberItemBase extends ConfigFieldItemBase {
/**
* Definitions of the contained properties.
*
* @var array
*/
static $propertyDefinitions;
/**
* {@inheritdoc}
*/
public function instanceSettingsForm(array $form, array &$form_state) {
$element = array();
$settings = $this->getFieldDefinition()->getFieldSettings();
$element['min'] = array(
'#type' => 'textfield',
'#title' => t('Minimum'),
'#default_value' => $settings['min'],
'#description' => t('The minimum value that should be allowed in this field. Leave blank for no minimum.'),
'#element_validate' => array('form_validate_number'),
);
$element['max'] = array(
'#type' => 'textfield',
'#title' => t('Maximum'),
'#default_value' => $settings['max'],
'#description' => t('The maximum value that should be allowed in this field. Leave blank for no maximum.'),
'#element_validate' => array('form_validate_number'),
);
$element['prefix'] = array(
'#type' => 'textfield',
'#title' => t('Prefix'),
'#default_value' => $settings['prefix'],
'#size' => 60,
'#description' => t("Define a string that should be prefixed to the value, like '$ ' or '&euro; '. Leave blank for none. Separate singular and plural values with a pipe ('pound|pounds')."),
);
$element['suffix'] = array(
'#type' => 'textfield',
'#title' => t('Suffix'),
'#default_value' => $settings['suffix'],
'#size' => 60,
'#description' => t("Define a string that should be suffixed to the value, like ' m', ' kb/s'. Leave blank for none. Separate singular and plural values with a pipe ('pound|pounds')."),
);
return $element;
}
/**
* {@inheritdoc}
*/
public function isEmpty() {
if (empty($this->value) && (string) $this->value !== '0') {
return TRUE;
}
return FALSE;
}
/**
* {@inheritdoc}
*/
public function getConstraints() {
$constraint_manager = \Drupal::typedData()->getValidationConstraintManager();
$constraints = parent::getConstraints();
$settings = $this->getFieldDefinition()->getFieldSettings();
$label = $this->getFieldDefinition()->getFieldLabel();
if (!empty($settings['min'])) {
$min = $settings['min'];
$constraints[] = $constraint_manager->create('ComplexData', array(
'value' => array(
'Range' => array(
'min' => $min,
'minMessage' => t('%name: the value may be no less than %min.', array('%name' => $label, '%min' => $min)),
)
),
));
}
if (!empty($settings['max'])) {
$max = $settings['max'];
$constraints[] = $constraint_manager->create('ComplexData', array(
'value' => array(
'Range' => array(
'max' => $max,
'maxMessage' => t('%name: the value may be no greater than %max.', array('%name' => $label, '%max' => $max)),
)
),
));
}
return $constraints;
}
}
<?php
/**
* @file
* Contains \Drupal\number\Type\DecimalItem.
*/
namespace Drupal\number\Type;
use Drupal\field\Plugin\field\field_type\LegacyConfigFieldItem;
/**
* Defines the 'number_decimal_field' entity field item.
*/
class DecimalItem extends LegacyConfigFieldItem {
/**
* Definitions of the contained properties.
*
* @see DecimalItem::getPropertyDefinitions()
*
* @var array
*/
static $propertyDefinitions;
/**
* Implements ComplexDataInterface::getPropertyDefinitions().
*/
public function getPropertyDefinitions() {
if (!isset(static::$propertyDefinitions)) {
static::$propertyDefinitions['value'] = array(
// Decimals are represented as string in PHP.
'type' => 'string',
'label' => t('Decimal value'),
);
}
return static::$propertyDefinitions;
}
}
<?php
/**
* @file
* Contains \Drupal\number\Type\FloatItem.
*/
namespace Drupal\number\Type;
use Drupal\field\Plugin\field\field_type\LegacyConfigFieldItem;
/**
* Defines the 'number_float_field' entity field item.
*/
class FloatItem extends LegacyConfigFieldItem {
/**
* Definitions of the contained properties.
*
* @see FloatItem::getPropertyDefinitions()
*
* @var array
*/
static $propertyDefinitions;
/**
* Implements ComplexDataInterface::getPropertyDefinitions().
*/
public function getPropertyDefinitions() {
if (!isset(static::$propertyDefinitions)) {
static::$propertyDefinitions['value'] = array(
'type' => 'float',
'label' => t('Float value'),
);
}
return static::$propertyDefinitions;
}
}
<?php
/**
* @file
* Contains \Drupal\number\Type\IntegerItem.
*/
namespace Drupal\number\Type;
use Drupal\field\Plugin\field\field_type\LegacyConfigFieldItem;
/**
* Defines the 'number_integer_field' entity field item.
*/
class IntegerItem extends LegacyConfigFieldItem {
/**
* Definitions of the contained properties.
*
* @see IntegerItem::getPropertyDefinitions()
*
* @var array
*/
static $propertyDefinitions;
/**
* Implements ComplexDataInterface::getPropertyDefinitions().
*/
public function getPropertyDefinitions() {
if (!isset(static::$propertyDefinitions)) {
static::$propertyDefinitions['value'] = array(
'type' => 'integer',
'label' => t('Integer value'),
);
}
return static::$propertyDefinitions;
}
}
<?php
/**
* @file
* Install, update, and uninstall functions for the Number module.
*/
/**
* Implements hook_field_schema().
*/
function number_field_schema($field) {
switch ($field['type']) {
case 'number_integer' :
$columns = array(
'value' => array(
'type' => 'int',
'not null' => FALSE
),
);
break;
case 'number_float' :
$columns = array(
'value' => array(
'type' => 'float',
'not null' => FALSE
),
);
break;
case 'number_decimal' :
$columns = array(
'value' => array(
'type' => 'numeric',
'precision' => $field['settings']['precision'],
'scale' => $field['settings']['scale'],
'not null' => FALSE
),
);
break;
}
return array(
'columns' => $columns,
);
}
......@@ -5,8 +5,6 @@
* Defines numeric field types.
*/
use Drupal\Core\Entity\EntityInterface;
/**
* Implements hook_help().
*/
......@@ -19,154 +17,3 @@ function number_help($path, $arg) {
return $output;
}
}
/**
* Implements hook_field_info().
*/
function number_field_info() {
return array(
'number_integer' => array(
'label' => t('Integer'),
'description' => t('This field stores a number in the database as an integer.'),
'instance_settings' => array('min' => '', 'max' => '', 'prefix' => '', 'suffix' => ''),
'default_widget' => 'number',
'default_formatter' => 'number_integer',
'class' => '\Drupal\number\Type\IntegerItem',
),
'number_decimal' => array(
'label' => t('Decimal'),
'description' => t('This field stores a number in the database in a fixed decimal format.'),
'settings' => array('precision' => 10, 'scale' => 2),
'instance_settings' => array('min' => '', 'max' => '', 'prefix' => '', 'suffix' => ''),
'default_widget' => 'number',
'default_formatter' => 'number_decimal',
'class' => '\Drupal\number\Type\DecimalItem',
),
'number_float' => array(
'label' => t('Float'),
'description' => t('This field stores a number in the database in a floating point format.'),
'instance_settings' => array('min' => '', 'max' => '', 'prefix' => '', 'suffix' => ''),
'default_widget' => 'number',
'default_formatter' => 'number_decimal',
'class' => '\Drupal\number\Type\FloatItem',
),
);
}
/**
* Implements hook_field_settings_form().
*/
function number_field_settings_form($field, $instance) {
$settings = $field['settings'];
$form = array();
if ($field['type'] == 'number_decimal') {
$form['precision'] = array(
'#type' => 'select',
'#title' => t('Precision'),
'#options' => drupal_map_assoc(range(10, 32)),
'#default_value' => $settings['precision'],
'#description' => t('The total number of digits to store in the database, including those to the right of the decimal.'),
'#disabled' => $field->hasData(),
);
$form['scale'] = array(
'#type' => 'select',
'#title' => t('Scale'),
'#options' => drupal_map_assoc(range(0, 10)),
'#default_value' => $settings['scale'],
'#description' => t('The number of digits to the right of the decimal.'),
'#disabled' => $field->hasData(),
);
}
return $form;
}
/**
* Implements hook_field_instance_settings_form().
*/
function number_field_instance_settings_form($field, $instance) {
$settings = $instance['settings'];
$form['min'] = array(
'#type' => 'textfield',
'#title' => t('Minimum'),
'#default_value' => $settings['min'],
'#description' => t('The minimum value that should be allowed in this field. Leave blank for no minimum.'),
'#element_validate' => array('form_validate_number'),
);
$form['max'] = array(
'#type' => 'textfield',
'#title' => t('Maximum'),
'#default_value' => $settings['max'],
'#description' => t('The maximum value that should be allowed in this field. Leave blank for no maximum.'),
'#element_validate' => array('form_validate_number'),
);
$form['prefix'] = array(
'#type' => 'textfield',
'#title' => t('Prefix'),
'#default_value' => $settings['prefix'],
'#size' => 60,
'#description' => t("Define a string that should be prefixed to the value, like '$ ' or '&euro; '. Leave blank for none. Separate singular and plural values with a pipe ('pound|pounds')."),
);
$form['suffix'] = array(
'#type' => 'textfield',
'#title' => t('Suffix'),
'#default_value' => $settings['suffix'],
'#size' => 60,
'#description' => t("Define a string that should be suffixed to the value, like ' m', ' kb/s'. Leave blank for none. Separate singular and plural values with a pipe ('pound|pounds')."),
);
return $form;
}
/**
* Implements hook_field_validate().
*
* Possible error codes:
* - number_min: The value is less than the allowed minimum value.
* - number_max: The value is greater than the allowed maximum value.
*/
function number_field_validate(EntityInterface $entity = NULL, $field, $instance, $langcode, $items, &$errors) {
foreach ($items as $delta => $item) {
if ($item['value'] != '') {
if (is_numeric($instance['settings']['min']) && $item['value'] < $instance['settings']['min']) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'number_min',
'message' => t('%name: the value may be no less than %min.', array('%name' => $instance['label'], '%min' => $instance['settings']['min'])),
);
}
if (is_numeric($instance['settings']['max']) && $item['value'] > $instance['settings']['max']) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'number_max',
'message' => t('%name: the value may be no greater than %max.', array('%name' => $instance['label'], '%max' => $instance['settings']['max'])),
);
}
}
}
}
/**
* Implements hook_field_presave().
*/
function number_field_presave(EntityInterface $entity, $field, $instance, $langcode, &$items) {
if ($field['type'] == 'number_decimal') {
// Let PHP round the value to ensure consistent behavior across storage
// backends.
foreach ($items as $delta => $item) {
if (isset($item['value'])) {
$items[$delta]['value'] = round($item['value'], $field['settings']['scale']);
}
}
}
}
/**
* Implements hook_field_is_empty().
*/
function number_field_is_empty($item, $field_type) {
if (empty($item['value']) && (string) $item['value'] !== '0') {
return TRUE;
}
return FALSE;
}
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