View source
<?php
namespace Drupal\tablefield\Plugin\Field\FieldType;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\TypedData\DataDefinition;
use Drupal\Core\TypedData\MapDataDefinition;
use Drupal\Core\Field\FieldItemBase;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
class TablefieldItem extends FieldItemBase {
public static function schema(FieldStorageDefinitionInterface $field_definition) {
return [
'columns' => [
'value' => [
'type' => 'blob',
'size' => 'big',
'serialize' => TRUE,
],
'format' => [
'type' => 'varchar',
'length' => 255,
'default value' => '',
],
'caption' => [
'type' => 'varchar',
'length' => 255,
'default value' => '',
],
],
];
}
public static function defaultFieldSettings() {
return [
'export' => 0,
'restrict_rebuild' => 1,
'restrict_import' => 1,
'lock_values' => 0,
'cell_processing' => 0,
'empty_rules' => [
'ignore_table_structure' => 0,
'ignore_table_header' => 0,
],
];
}
public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
$form = [];
$settings = $this
->getSettings();
$form['default_message'] = [
'#type' => 'markup',
'#markup' => $this
->t('To specify a default table, use the "Default Value" above. There you can specify a default number of rows/columns and values.'),
];
$form['export'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Allow users to export table data as CSV'),
'#default_value' => $settings['export'],
];
$form['restrict_rebuild'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Restrict rebuilding to users with the permission "rebuild tablefield"'),
'#default_value' => $settings['restrict_rebuild'],
];
$form['restrict_import'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Restrict importing to users with the permission "import tablefield"'),
'#default_value' => $settings['restrict_import'],
];
$form['lock_values'] = [
'#type' => 'checkbox',
'#title' => 'Lock cell default values from further edits during node add/edit. Most commonly used to have fixed values for the header.',
'#default_value' => $settings['lock_values'],
];
$form['cell_processing'] = [
'#type' => 'radios',
'#title' => $this
->t('Table cell processing'),
'#default_value' => $settings['cell_processing'],
'#options' => [
$this
->t('Plain text'),
$this
->t('Filtered text (user selects input format)'),
],
];
$form['empty_rules'] = [
'#type' => 'details',
'#title' => $this
->t('Rules for evaluating whether tablefield item should be considered empty'),
'#open' => FALSE,
];
$form['empty_rules']['ignore_table_structure'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Ignore table structure changes'),
'#description' => $this
->t('If checked, table structure, i.e. number of rows and cols will not be considered when evaluating whether tablefield item is empty or not. If unchecked, a table structure which is different from the one set in defaults will result in the tablefield item being considered not empty.'),
'#default_value' => $settings['empty_rules']['ignore_table_structure'],
];
$form['empty_rules']['ignore_table_header'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Ignore table header'),
'#description' => $this
->t('If checked, tablefield item will be considered empty even if it does have a table header, i.e. even if first row of the table contains non-empty cells.'),
'#default_value' => $settings['empty_rules']['ignore_table_header'],
];
return $form;
}
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
$properties['table_value'] = DataDefinition::create('string')
->setLabel(t('Stringified table value'))
->setDescription(t('The stringified value of the table.'))
->setComputed(TRUE)
->setClass('\\Drupal\\tablefield\\TableValue');
$properties['value'] = MapDataDefinition::create()
->setLabel(t('Table data'))
->setDescription(t('Stores tabular data.'));
$properties['format'] = DataDefinition::create('filter_format')
->setLabel(t('Text format'));
$properties['caption'] = DataDefinition::create('string')
->setLabel(t('Table Caption'));
return $properties;
}
public function setValue($values, $notify = TRUE) {
if (!isset($values)) {
return;
}
elseif (!empty($values['tablefield'])) {
$values['rebuild'] = $values['tablefield']['rebuild'];
$values['value'] = $values['tablefield']['table'];
unset($values['tablefield']);
unset($values['rebuild']['rebuild']);
}
elseif (!empty($values['value']['tablefield'])) {
$values['rebuild'] = $values['value']['tablefield']['rebuild'];
$values['value'] = $values['value']['tablefield']['table'];
unset($values['rebuild']['rebuild']);
}
elseif (empty($values['rebuild'])) {
if (array_key_exists('value', $values) && array_key_exists('caption', $values['value'])) {
unset($values['value']['caption']);
}
$values['rebuild']['rows'] = isset($values['value']) ? count($values['value']) : 0;
$values['rebuild']['cols'] = isset($values['value'][0]) ? count($values['value'][0]) : 0;
}
if (isset($values['caption'])) {
$values['value']['caption'] = $values['caption'];
}
$lock = $this
->getFieldDefinition()
->getSetting('lock_values');
if ($lock) {
foreach ($values['value'] as $key => $value) {
if (is_array($value)) {
ksort($value);
$values['value'][$key] = $value;
}
}
if (is_array($values['value'])) {
ksort($values['value']);
}
}
parent::setValue($values, $notify);
}
public static function generateSampleValue(FieldDefinitionInterface $field_definition) {
return [
'value' => [
[
'Header 1',
'Header 2',
],
[
'Data 1',
'Data 2',
],
],
'rebuild' => [
'rows' => 2,
'cols' => 2,
],
];
}
public function isEmpty() {
$value = $this
->getValue();
$empty_rules = $this
->getFieldDefinition()
->getSetting('empty_rules');
$in_settings = \Drupal::request()
->get(RouteObjectInterface::ROUTE_NAME) == 'entity.field_config.node_field_edit_form';
if (!empty($value) && isset($value['value']) && is_array($value['value'])) {
if (!empty($value['caption'])) {
return FALSE;
}
if (!$in_settings && $empty_rules['ignore_table_header']) {
array_shift($value['value']);
}
foreach ($value['value'] as $row) {
if (is_array($row)) {
foreach ($row as $cell) {
if (!empty($cell)) {
return FALSE;
}
}
}
}
}
if (empty($empty_rules['ignore_table_structure'])) {
$default_value = $this
->getFieldDefinition()
->getDefaultValueLiteral();
if (!$in_settings && !empty($default_value[$this->name])) {
$default_structure = $default_value[$this->name]['rebuild'];
}
else {
$default_structure = [
'rows' => \Drupal::config('tablefield.settings')
->get('rows'),
'cols' => \Drupal::config('tablefield.settings')
->get('cols'),
];
}
if (!empty($value['rebuild']) && $value['rebuild'] != $default_structure) {
return FALSE;
}
}
return TRUE;
}
}