Commit 5909b03b authored by alexpott's avatar alexpott

Issue #2169983 by plopesc, yched: Move type-specific logic from ListItemBase...

Issue #2169983 by plopesc, yched: Move type-specific logic from ListItemBase to the appropriate subclass.
parent bbe2af1a
......@@ -7,7 +7,11 @@
namespace Drupal\options\Plugin\Field\FieldType;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\TypedData\AllowedValuesInterface;
use Drupal\Core\TypedData\DataDefinition;
/**
......@@ -15,7 +19,6 @@
*
* @FieldType(
* id = "list_boolean",
* module = "options",
* label = @Translation("Boolean"),
* description = @Translation("This field stores simple on/off or yes/no options."),
* default_widget = "options_buttons",
......@@ -26,20 +29,34 @@
* }
* )
*/
class ListBooleanItem extends ListItemBase {
class ListBooleanItem extends FieldItemBase implements AllowedValuesInterface {
/**
* {@inheritdoc}
*/
public static function schema(FieldDefinitionInterface $field_definition) {
return parent::schema($field_definition) + array(
'columns' => array(
'value' => array(
'type' => 'int',
'not null' => FALSE,
),
),
);
public function getPossibleValues(AccountInterface $account = NULL) {
return array_keys($this->getSettableOptions($account));
}
/**
* {@inheritdoc}
*/
public function getPossibleOptions(AccountInterface $account = NULL) {
return $this->getSettableOptions($account);
}
/**
* {@inheritdoc}
*/
public function getSettableValues(AccountInterface $account = NULL) {
return array_keys($this->getSettableOptions($account));
}
/**
* {@inheritdoc}
*/
public function getSettableOptions(AccountInterface $account = NULL) {
return options_allowed_values($this->getFieldDefinition(), $this->getEntity());
}
/**
......@@ -52,4 +69,92 @@ public static function propertyDefinitions(FieldDefinitionInterface $field_defin
return $properties;
}
/**
* {@inheritdoc}
*/
public static function schema(FieldDefinitionInterface $field_definition) {
return array(
'columns' => array(
'value' => array(
'type' => 'int',
'not null' => FALSE,
),
),
'indexes' => array(
'value' => array('value'),
),
);
}
/**
* {@inheritdoc}
*/
public function isEmpty() {
return empty($this->value) && (string) $this->value !== '0';
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, array &$form_state, $has_data) {
$allowed_values = $this->getSetting('allowed_values');
$allowed_values_function = $this->getSetting('allowed_values_function');
$values = $allowed_values;
$off_value = array_shift($values);
$on_value = array_shift($values);
$element['allowed_values'] = array(
'#type' => 'value',
'#description' => '',
'#value_callback' => array(get_class($this), 'optionsBooleanAllowedValues'),
'#access' => empty($allowed_values_function),
);
$element['allowed_values']['on'] = array(
'#type' => 'textfield',
'#title' => t('On value'),
'#default_value' => $on_value,
'#required' => FALSE,
'#description' => t('If left empty, "1" will be used.'),
// Change #parents to make sure the element is not saved into field
// settings.
'#parents' => array('on'),
);
$element['allowed_values']['off'] = array(
'#type' => 'textfield',
'#title' => t('Off value'),
'#default_value' => $off_value,
'#required' => FALSE,
'#description' => t('If left empty, "0" will be used.'),
// Change #parents to make sure the element is not saved into field
// settings.
'#parents' => array('off'),
);
// Link the allowed value to the on / off elements to prepare for the rare
// case of an alter changing #parents.
$element['allowed_values']['#on_parents'] = &$element['allowed_values']['on']['#parents'];
$element['allowed_values']['#off_parents'] = &$element['allowed_values']['off']['#parents'];
$element['allowed_values_function'] = array(
'#type' => 'item',
'#title' => t('Allowed values list'),
'#markup' => t('The value of this field is being determined by the %function function and may not be changed.', array('%function' => $allowed_values_function)),
'#access' => !empty($allowed_values_function),
'#value' => $allowed_values_function,
);
return $element;
}
/**
* Form element #value_callback: assembles the allowed values for 'boolean'
* fields.
*/
public static function optionsBooleanAllowedValues($element, $input, $form_state) {
$on = NestedArray::getValue($form_state['input'], $element['#on_parents']);
$off = NestedArray::getValue($form_state['input'], $element['#off_parents']);
return array($off, $on);
}
}
......@@ -15,7 +15,6 @@
*
* @FieldType(
* id = "list_float",
* module = "options",
* label = @Translation("List (float)"),
* description = @Translation("This field stores float values from a list of allowed 'value => label' pairs, i.e. 'Fraction': 0 => 0, .25 => 1/4, .75 => 3/4, 1 => 1."),
* default_widget = "options_select",
......@@ -28,28 +27,71 @@
*/
class ListFloatItem extends ListItemBase {
/**
* {@inheritdoc}
*/
public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
$properties['value'] = DataDefinition::create('float')
->setLabel(t('Float value'));
return $properties;
}
/**
* {@inheritdoc}
*/
public static function schema(FieldDefinitionInterface $field_definition) {
return parent::schema($field_definition) + array(
'columns' => array(
'value' => array(
'type' => 'float',
'not null' => FALSE,
),
),
return array(
'columns' => array(
'value' => array(
'type' => 'float',
'not null' => FALSE,
),
),
'indexes' => array(
'value' => array('value'),
),
);
}
/**
* {@inheritdoc}
*/
public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
$properties['value'] = DataDefinition::create('float')
->setLabel(t('Float value'));
protected function allowedValuesDescription() {
$description = '<p>' . t('The possible values this field can contain. Enter one value per line, in the format key|label.');
$description .= '<br/>' . t('The key is the stored value, and must be numeric. The label will be used in displayed values and edit forms.');
$description .= '<br/>' . t('The label is optional: if a line contains a single number, it will be used as key and label.');
$description .= '<br/>' . t('Lists of labels are also accepted (one label per line), only if the field does not hold any values yet. Numeric keys will be automatically generated from the positions in the list.');
$description .= '</p>';
$description .= '<p>' . t('Allowed HTML tags in labels: @tags', array('@tags' => _field_filter_xss_display_allowed_tags())) . '</p>';
return $description;
}
return $properties;
/**
* {@inheritdoc}
*/
protected static function extractAllowedValues($string, $has_data) {
$values = parent::extractAllowedValues($string, $has_data);
if ($values) {
$keys = array_keys($values);
$labels = array_values($values);
$keys = array_map(function ($key) {
// Float keys are represented as strings and need to be disambiguated
// ('.5' is '0.5').
return is_numeric($key) ? (string) (float) $key : $key;
}, $keys);
return array_combine($keys, $labels);
}
}
/**
* {@inheritdoc}
*/
protected static function validateAllowedValue($option) {
if (!is_numeric($option)) {
return t('Allowed values list: each key must be a valid integer or decimal.');
}
}
}
......@@ -15,7 +15,6 @@
*
* @FieldType(
* id = "list_integer",
* module = "options",
* label = @Translation("List (integer)"),
* description = @Translation("This field stores integer values from a list of allowed 'value => label' pairs, i.e. 'Lifetime in days': 1 => 1 day, 7 => 1 week, 31 => 1 month."),
* default_widget = "options_select",
......@@ -28,28 +27,53 @@
*/
class ListIntegerItem extends ListItemBase {
/**
* {@inheritdoc}
*/
public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
$properties['value'] = DataDefinition::create('integer')
->setLabel(t('Integer value'));
return $properties;
}
/**
* {@inheritdoc}
*/
public static function schema(FieldDefinitionInterface $field_definition) {
return parent::schema($field_definition) + array(
'columns' => array(
'value' => array(
'type' => 'int',
'not null' => FALSE,
),
),
return array(
'columns' => array(
'value' => array(
'type' => 'int',
'not null' => FALSE,
),
),
'indexes' => array(
'value' => array('value'),
),
);
}
/**
* {@inheritdoc}
*/
public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
$properties['value'] = DataDefinition::create('integer')
->setLabel(t('Integer value'));
protected function allowedValuesDescription() {
$description = '<p>' . t('The possible values this field can contain. Enter one value per line, in the format key|label.');
$description .= '<br/>' . t('The key is the stored value, and must be numeric. The label will be used in displayed values and edit forms.');
$description .= '<br/>' . t('The label is optional: if a line contains a single number, it will be used as key and label.');
$description .= '<br/>' . t('Lists of labels are also accepted (one label per line), only if the field does not hold any values yet. Numeric keys will be automatically generated from the positions in the list.');
$description .= '</p>';
$description .= '<p>' . t('Allowed HTML tags in labels: @tags', array('@tags' => _field_filter_xss_display_allowed_tags())) . '</p>';
return $description;
}
return $properties;
/**
* {@inheritdoc}
*/
protected static function validateAllowedValue($option) {
if (!preg_match('/^-?\d+$/', $option)) {
return t('Allowed values list: keys must be integers.');
}
}
}
......@@ -15,7 +15,6 @@
*
* @FieldType(
* id = "list_text",
* module = "options",
* label = @Translation("List (text)"),
* description = @Translation("This field stores text values from a list of allowed 'value => label' pairs, i.e. 'US States': IL => Illinois, IA => Iowa, IN => Indiana."),
* default_widget = "options_select",
......@@ -28,31 +27,55 @@
*/
class ListTextItem extends ListItemBase {
/**
* {@inheritdoc}
*/
public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
$constraints = array('Length' => array('max' => 255));
$properties['value'] = DataDefinition::create('string')
->setLabel(t('Text value'))
->setConstraints($constraints);
return $properties;
}
/**
* {@inheritdoc}
*/
public static function schema(FieldDefinitionInterface $field_definition) {
return parent::schema($field_definition) + array(
'columns' => array(
'value' => array(
'type' => 'varchar',
'length' => 255,
'not null' => FALSE,
),
),
return array(
'columns' => array(
'value' => array(
'type' => 'varchar',
'length' => 255,
'not null' => FALSE,
),
),
'indexes' => array(
'value' => array('value'),
),
);
}
/**
* {@inheritdoc}
*/
public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
$constraints = array('Length' => array('max' => 255));
$properties['value'] = DataDefinition::create('string')
->setLabel(t('Text value'))
->setConstraints($constraints);
protected function allowedValuesDescription() {
$description = '<p>' . t('The possible values this field can contain. Enter one value per line, in the format key|label.');
$description .= '<br/>' . t('The key is the stored value. The label will be used in displayed values and edit forms.');
$description .= '<br/>' . t('The label is optional: if a line contains a single string, it will be used as key and label.');
$description .= '</p>';
$description .= '<p>' . t('Allowed HTML tags in labels: @tags', array('@tags' => _field_filter_xss_display_allowed_tags())) . '</p>';
return $description;
}
return $properties;
/**
* {@inheritdoc}
*/
protected static function validateAllowedValue($option) {
if (drupal_strlen($option) > 255) {
return t('Allowed values list: each key must be a string at most 255 characters long.');
}
}
}
......@@ -5,7 +5,6 @@
* Defines selection, check box and radio button widgets for text and numeric fields.
*/
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\field\FieldConfigInterface;
......@@ -33,15 +32,6 @@ function options_help($path, $arg) {
}
}
/**
* Form element #value_callback: assembles the allowed values for 'boolean' fields.
*/
function options_field_settings_form_value_boolean_allowed_values($element, $input, $form_state) {
$on = NestedArray::getValue($form_state['input'], $element['#on_parents']);
$off = NestedArray::getValue($form_state['input'], $element['#off_parents']);
return array($off, $on);
}
/**
* Implements hook_ENTITY_TYPE_update() for 'field_config'.
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment