Issue #2015691 by plopesc, swentel: Convert field type to typed data plugin for number module.
parent
57dc876717
commit
e30e80c560
|
@ -0,0 +1,103 @@
|
|||
<?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'));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
<?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,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
<?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,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
<?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 '€ '. 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
<?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;
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
<?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;
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
<?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;
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
<?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 '€ '. 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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue