From d6201229d24373d927134a3047cbf2e129c4ce26 Mon Sep 17 00:00:00 2001 From: Joao Ventura Date: Sun, 20 Sep 2015 18:39:54 +0200 Subject: Issue #784672 by jcnventura, bruvers, lokapujya, floretan, vpeltot, wjaspers, c960657: Allow text field to enforce a specific text format --- core/modules/block_content/block_content.module | 5 +- .../block_content_body_field.yml | 1 + .../config/install/field.field.node.book.body.yml | 1 + .../src/Tests/ConfigTranslationListUiTest.php | 5 +- .../Tests/Migrate/d6/MigrateFieldInstanceTest.php | 5 +- .../config/install/field.field.node.forum.body.yml | 1 + core/modules/node/node.module | 5 +- .../field.field.node.options_install_test.body.yml | 1 + core/modules/text/config/schema/text.schema.yml | 17 +++++ .../src/Plugin/Field/FieldType/TextItemBase.php | 23 +++++++ .../Plugin/Field/FieldType/TextWithSummaryItem.php | 2 +- .../Plugin/Field/FieldWidget/TextareaWidget.php | 9 +++ .../Plugin/Field/FieldWidget/TextfieldWidget.php | 9 +++ core/modules/text/src/Tests/TextFieldTest.php | 75 +++++++++++++++++++++- .../Tests/Entity/ViewEntityDependenciesTest.php | 5 +- .../field.field.block_content.basic.body.yml | 1 + .../field.field.comment.comment.comment_body.yml | 3 +- .../install/field.field.node.article.body.yml | 1 + .../config/install/field.field.node.page.body.yml | 1 + 19 files changed, 161 insertions(+), 9 deletions(-) diff --git a/core/modules/block_content/block_content.module b/core/modules/block_content/block_content.module index 04a1e6c..209d766 100644 --- a/core/modules/block_content/block_content.module +++ b/core/modules/block_content/block_content.module @@ -83,7 +83,10 @@ function block_content_add_body_field($block_type_id, $label = 'Body') { 'field_storage' => FieldStorageConfig::loadByName('block_content', 'body'), 'bundle' => $block_type_id, 'label' => $label, - 'settings' => array('display_summary' => FALSE), + 'settings' => [ + 'display_summary' => FALSE, + 'allowed_formats' => [], + ], )); $field->save(); diff --git a/core/modules/block_content/migration_templates/block_content_body_field.yml b/core/modules/block_content/migration_templates/block_content_body_field.yml index 41484f8..388a8f7 100644 --- a/core/modules/block_content/migration_templates/block_content_body_field.yml +++ b/core/modules/block_content/migration_templates/block_content_body_field.yml @@ -12,6 +12,7 @@ source: field_name: body label: Body display_summary: false + allowed_formats: { } ids: entity_type: type: string diff --git a/core/modules/book/config/install/field.field.node.book.body.yml b/core/modules/book/config/install/field.field.node.book.body.yml index 4c128b6..fbc6150 100644 --- a/core/modules/book/config/install/field.field.node.book.body.yml +++ b/core/modules/book/config/install/field.field.node.book.body.yml @@ -18,5 +18,6 @@ default_value: { } default_value_callback: '' settings: display_summary: true + allowed_formats: { } third_party_settings: { } field_type: text_with_summary diff --git a/core/modules/config_translation/src/Tests/ConfigTranslationListUiTest.php b/core/modules/config_translation/src/Tests/ConfigTranslationListUiTest.php index fceb41d..1aa9735 100644 --- a/core/modules/config_translation/src/Tests/ConfigTranslationListUiTest.php +++ b/core/modules/config_translation/src/Tests/ConfigTranslationListUiTest.php @@ -403,7 +403,10 @@ public function doFieldListTest() { 'field_storage' => FieldStorageConfig::loadByName('block_content', 'body'), 'bundle' => $block_content_type->id(), 'label' => 'Body', - 'settings' => array('display_summary' => FALSE), + 'settings' => [ + 'display_summary' => FALSE, + 'allowed_formats' => [], + ], )); $field->save(); diff --git a/core/modules/field/src/Tests/Migrate/d6/MigrateFieldInstanceTest.php b/core/modules/field/src/Tests/Migrate/d6/MigrateFieldInstanceTest.php index 2b04399..5f9b2e7 100644 --- a/core/modules/field/src/Tests/Migrate/d6/MigrateFieldInstanceTest.php +++ b/core/modules/field/src/Tests/Migrate/d6/MigrateFieldInstanceTest.php @@ -78,7 +78,10 @@ public function testFieldInstanceSettings() { // Test a text field. $field = FieldConfig::load('node.story.field_test'); $this->assertIdentical('Text Field', $field->label()); - $expected = array('max_length' => 255); + $expected = [ + 'allowed_formats' => [], + 'max_length' => 255, + ]; $this->assertIdentical($expected, $field->getSettings()); $this->assertIdentical('text for default value', $entity->field_test->value); diff --git a/core/modules/forum/config/install/field.field.node.forum.body.yml b/core/modules/forum/config/install/field.field.node.forum.body.yml index 279f160..6d9e46f 100644 --- a/core/modules/forum/config/install/field.field.node.forum.body.yml +++ b/core/modules/forum/config/install/field.field.node.forum.body.yml @@ -18,5 +18,6 @@ default_value: { } default_value_callback: '' settings: display_summary: true + allowed_formats: { } third_party_settings: { } field_type: text_with_summary diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 7c371d6..338daed 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -328,7 +328,10 @@ function node_add_body_field(NodeTypeInterface $type, $label = 'Body') { 'field_storage' => $field_storage, 'bundle' => $type->id(), 'label' => $label, - 'settings' => array('display_summary' => TRUE), + 'settings' => [ + 'display_summary' => TRUE, + 'allowed_formats' => [], + ], )); $field->save(); diff --git a/core/modules/options/tests/options_config_install_test/config/install/field.field.node.options_install_test.body.yml b/core/modules/options/tests/options_config_install_test/config/install/field.field.node.options_install_test.body.yml index 2078a84..ac288b8 100644 --- a/core/modules/options/tests/options_config_install_test/config/install/field.field.node.options_install_test.body.yml +++ b/core/modules/options/tests/options_config_install_test/config/install/field.field.node.options_install_test.body.yml @@ -16,5 +16,6 @@ default_value: { } default_value_callback: '' settings: display_summary: true + allowed_formats: { } third_party_settings: { } field_type: text_with_summary diff --git a/core/modules/text/config/schema/text.schema.yml b/core/modules/text/config/schema/text.schema.yml index dfc92cd..6bc711a 100644 --- a/core/modules/text/config/schema/text.schema.yml +++ b/core/modules/text/config/schema/text.schema.yml @@ -19,6 +19,12 @@ field.storage_settings.text: field.field_settings.text: type: mapping label: 'Text (formatted) settings' + mapping: + allowed_formats: + type: sequence + label: 'Allowed text formats' + sequence: + type: string field.value.text: type: mapping @@ -38,6 +44,12 @@ field.storage_settings.text_long: field.field_settings.text_long: label: 'Text (formatted, long) settings' type: mapping + mapping: + allowed_formats: + type: sequence + label: 'Allowed text formats' + sequence: + type: string field.value.text_long: type: mapping @@ -61,6 +73,11 @@ field.field_settings.text_with_summary: display_summary: type: boolean label: 'Summary input' + allowed_formats: + type: sequence + label: 'Allowed text formats' + sequence: + type: string field.value.text_with_summary: type: mapping diff --git a/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php b/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php index a3697e8..e19cc48 100644 --- a/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php +++ b/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php @@ -12,12 +12,35 @@ use Drupal\Core\Field\FieldItemBase; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\TypedData\DataDefinition; +use Drupal\Core\Form\FormStateInterface; /** * Base class for 'text' configurable field types. */ abstract class TextItemBase extends FieldItemBase { + + /** + * {@inheritdoc} + */ + public static function defaultFieldSettings() { + return ['allowed_formats' => []] + parent::defaultFieldSettings(); + } + + public function fieldSettingsForm(array $form, FormStateInterface $form_state) { + $element = parent::fieldSettingsForm($form, $form_state); + $settings = $this->getSettings(); + + $element['allowed_formats'] = [ + '#type' => 'checkboxes', + '#title' => t('Allowed text formats'), + '#options' => $this->getProperties()['format']->getPossibleOptions(), + '#default_value' => $settings['allowed_formats'], + ]; + + return $element; + } + /** * {@inheritdoc} */ diff --git a/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php b/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php index 413ad47..22ac73c 100644 --- a/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php +++ b/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php @@ -90,7 +90,7 @@ public function isEmpty() { * {@inheritdoc} */ public function fieldSettingsForm(array $form, FormStateInterface $form_state) { - $element = array(); + $element = parent::fieldSettingsForm($form, $form_state); $settings = $this->getSettings(); $element['display_summary'] = array( diff --git a/core/modules/text/src/Plugin/Field/FieldWidget/TextareaWidget.php b/core/modules/text/src/Plugin/Field/FieldWidget/TextareaWidget.php index 0ac3151..259ef64 100644 --- a/core/modules/text/src/Plugin/Field/FieldWidget/TextareaWidget.php +++ b/core/modules/text/src/Plugin/Field/FieldWidget/TextareaWidget.php @@ -30,11 +30,20 @@ class TextareaWidget extends StringTextareaWidget { */ public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { $main_widget = parent::formElement($items, $delta, $element, $form, $form_state); + $allowed_formats_setting = $this->getFieldSetting('allowed_formats'); $element = $main_widget['value']; $element['#type'] = 'text_format'; $element['#format'] = $items[$delta]->format; $element['#base_type'] = $main_widget['value']['#type']; + + if (is_array($allowed_formats_setting)) { + $allowed_formats = array_filter($allowed_formats_setting); + if (!empty($allowed_formats) && !$this->isDefaultValueWidget($form_state)) { + $element['#allowed_formats'] = $allowed_formats; + } + } + return $element; } diff --git a/core/modules/text/src/Plugin/Field/FieldWidget/TextfieldWidget.php b/core/modules/text/src/Plugin/Field/FieldWidget/TextfieldWidget.php index ab2f19a..1834053 100644 --- a/core/modules/text/src/Plugin/Field/FieldWidget/TextfieldWidget.php +++ b/core/modules/text/src/Plugin/Field/FieldWidget/TextfieldWidget.php @@ -30,11 +30,20 @@ class TextfieldWidget extends StringTextfieldWidget { */ public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { $main_widget = parent::formElement($items, $delta, $element, $form, $form_state); + $allowed_formats_setting = $this->getFieldSetting('allowed_formats'); $element = $main_widget['value']; $element['#type'] = 'text_format'; $element['#format'] = isset($items[$delta]->format) ? $items[$delta]->format : NULL; $element['#base_type'] = $main_widget['value']['#type']; + + if (is_array($allowed_formats_setting)) { + $allowed_formats = array_filter($allowed_formats_setting); + if (!empty($allowed_formats) && !$this->isDefaultValueWidget($form_state)) { + $element['#allowed_formats'] = $allowed_formats; + } + } + return $element; } diff --git a/core/modules/text/src/Tests/TextFieldTest.php b/core/modules/text/src/Tests/TextFieldTest.php index a22bc5b..6b2913f 100644 --- a/core/modules/text/src/Tests/TextFieldTest.php +++ b/core/modules/text/src/Tests/TextFieldTest.php @@ -84,6 +84,77 @@ function testTextfieldWidgetsFormatted() { } /** + * Test widgets for fields with selected allowed formats. + */ + function testTextfieldWidgetsAllowedFormats() { + + // Create one text format. + $this->drupalLogin($this->adminUser); + $edit = [ + 'format' => Unicode::strtolower($this->randomMachineName()), + 'name' => $this->randomMachineName(), + ]; + $this->drupalPostForm('admin/config/content/formats/add', $edit, t('Save configuration')); + filter_formats_reset(); + $format1 = entity_load('filter_format', $edit['format']); + + // Create a second text format. + $edit = [ + 'format' => Unicode::strtolower($this->randomMachineName()), + 'name' => $this->randomMachineName(), + ]; + $this->drupalPostForm('admin/config/content/formats/add', $edit, t('Save configuration')); + filter_formats_reset(); + $format2 = entity_load('filter_format', $edit['format']); + + // Grant access to both formats to the user. + $roles = $this->webUser->getRoles(); + $rid = $roles[0]; + user_role_grant_permissions($rid, [ + $format1->getPermissionName(), + $format2->getPermissionName(), + ]); + + // Create a field with multiple formats allowed. + $field_name = Unicode::strtolower($this->randomMachineName()); + $field_storage = entity_create('field_storage_config', [ + 'field_name' => $field_name, + 'entity_type' => 'entity_test', + 'type' => 'text', + ]); + $field_storage->save(); + $field = entity_create('field_config', [ + 'field_storage' => $field_storage, + 'bundle' => 'entity_test', + 'label' => $this->randomMachineName() . '_label', + 'settings' => ['allowed_formats' => [$format1->id(), $format2->id()]], + ]); + $field->save(); + entity_get_form_display('entity_test', 'entity_test', 'default') + ->setComponent($field_name, [ + 'type' => 'text_textfield', + ]) + ->save(); + entity_get_display('entity_test', 'entity_test', 'full') + ->setComponent($field_name) + ->save(); + + // Display the creation form. + $this->drupalLogin($this->webUser); + $this->drupalGet('entity_test/add'); + $this->assertFieldByName("{$field_name}[0][value]", NULL, 'Widget is displayed'); + $this->assertFieldByName("{$field_name}[0][format]", NULL, 'Format selector is displayed'); + + // Change field to allow only one format. + $field->setSetting('allowed_formats', [$format1->id()]); + $field->save(); + // We shouldn't have the 'format' selector since only one format is allowed. + $this->drupalGet('entity_test/add'); + $this->assertFieldByName("{$field_name}[0][value]", NULL, 'Widget is displayed'); + $this->assertNoFieldByName("{$field_name}[0][format]", NULL, 'Format selector is not displayed'); + } + + /** * Helper function for testTextfieldWidgetsFormatted(). */ function _testTextfieldWidgetsFormatted($field_type, $widget_type) { @@ -124,8 +195,8 @@ function _testTextfieldWidgetsFormatted($field_type, $widget_type) { // Display the creation form. Since the user only has access to one format, // no format selector will be displayed. $this->drupalGet('entity_test/add'); - $this->assertFieldByName("{$field_name}[0][value]", '', 'Widget is displayed'); - $this->assertNoFieldByName("{$field_name}[0][format]", '', 'Format selector is not displayed'); + $this->assertFieldByName("{$field_name}[0][value]", NULL, 'Widget is displayed'); + $this->assertNoFieldByName("{$field_name}[0][format]", NULL, 'Format selector is not displayed'); // Submit with data that should be filtered. $value = '' . $this->randomMachineName() . ''; diff --git a/core/modules/views/src/Tests/Entity/ViewEntityDependenciesTest.php b/core/modules/views/src/Tests/Entity/ViewEntityDependenciesTest.php index e8a7c1b..ad8b5cb 100644 --- a/core/modules/views/src/Tests/Entity/ViewEntityDependenciesTest.php +++ b/core/modules/views/src/Tests/Entity/ViewEntityDependenciesTest.php @@ -76,7 +76,10 @@ protected function setUp() { 'field_storage' => FieldStorageConfig::loadByName('node', 'body'), 'bundle' => $content_type->id(), 'label' => $this->randomMachineName() . '_body', - 'settings' => array('display_summary' => TRUE), + 'settings' => [ + 'display_summary' => TRUE, + 'allowed_formats' => [], + ], ))->save(); ViewTestData::createTestViews(get_class($this), array('views_test_config')); diff --git a/core/profiles/standard/config/install/field.field.block_content.basic.body.yml b/core/profiles/standard/config/install/field.field.block_content.basic.body.yml index e115700..14e481a 100644 --- a/core/profiles/standard/config/install/field.field.block_content.basic.body.yml +++ b/core/profiles/standard/config/install/field.field.block_content.basic.body.yml @@ -18,5 +18,6 @@ default_value: { } default_value_callback: '' settings: display_summary: false + allowed_formats: { } third_party_settings: { } field_type: text_with_summary diff --git a/core/profiles/standard/config/install/field.field.comment.comment.comment_body.yml b/core/profiles/standard/config/install/field.field.comment.comment.comment_body.yml index 30aaabe..8342f44 100644 --- a/core/profiles/standard/config/install/field.field.comment.comment.comment_body.yml +++ b/core/profiles/standard/config/install/field.field.comment.comment.comment_body.yml @@ -16,6 +16,7 @@ required: true translatable: true default_value: { } default_value_callback: '' -settings: { } +settings: + allowed_formats: { } third_party_settings: { } field_type: text_long diff --git a/core/profiles/standard/config/install/field.field.node.article.body.yml b/core/profiles/standard/config/install/field.field.node.article.body.yml index e2cdb3a..e6a9e32 100644 --- a/core/profiles/standard/config/install/field.field.node.article.body.yml +++ b/core/profiles/standard/config/install/field.field.node.article.body.yml @@ -18,5 +18,6 @@ default_value: { } default_value_callback: '' settings: display_summary: true + allowed_formats: { } third_party_settings: { } field_type: text_with_summary diff --git a/core/profiles/standard/config/install/field.field.node.page.body.yml b/core/profiles/standard/config/install/field.field.node.page.body.yml index 57bb0b0..5829298 100644 --- a/core/profiles/standard/config/install/field.field.node.page.body.yml +++ b/core/profiles/standard/config/install/field.field.node.page.body.yml @@ -18,5 +18,6 @@ default_value: { } default_value_callback: '' settings: display_summary: true + allowed_formats: { } third_party_settings: { } field_type: text_with_summary -- 2.5.2