diff --git a/core/modules/block_content/block_content.module b/core/modules/block_content/block_content.module index e0b5729..b0a1d6a 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 b97b9fa..3fdd7c2 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,4 +18,5 @@ default_value: { } default_value_callback: '' settings: display_summary: true + allowed_formats: { } 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 8bd3d71..a6ac0e1 100644 --- a/core/modules/config_translation/src/Tests/ConfigTranslationListUiTest.php +++ b/core/modules/config_translation/src/Tests/ConfigTranslationListUiTest.php @@ -404,7 +404,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/tests/src/Kernel/Migrate/d6/MigrateFieldInstanceTest.php b/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldInstanceTest.php index b3fac3f..131c5b7 100644 --- a/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldInstanceTest.php +++ b/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldInstanceTest.php @@ -26,7 +26,7 @@ public function testFieldInstanceMigration() { $field = FieldConfig::load('node.story.field_test'); $this->assertIdentical('Text Field', $field->label()); // field_test is a text_long field, which have no settings. - $this->assertIdentical([], $field->getSettings()); + $this->assertIdentical(['allowed_formats' => []], $field->getSettings()); $this->assertIdentical('text for default value', $entity->field_test->value); // Test a number field. diff --git a/core/modules/forum/config/optional/field.field.comment.comment_forum.comment_body.yml b/core/modules/forum/config/optional/field.field.comment.comment_forum.comment_body.yml index 215199c..8c6fa4c 100644 --- a/core/modules/forum/config/optional/field.field.comment.comment_forum.comment_body.yml +++ b/core/modules/forum/config/optional/field.field.comment.comment_forum.comment_body.yml @@ -16,5 +16,6 @@ required: true translatable: true default_value: { } default_value_callback: '' -settings: { } +settings: + allowed_formats: { } field_type: text_long diff --git a/core/modules/forum/config/optional/field.field.node.forum.body.yml b/core/modules/forum/config/optional/field.field.node.forum.body.yml index af6f7ad..57fa67e 100644 --- a/core/modules/forum/config/optional/field.field.node.forum.body.yml +++ b/core/modules/forum/config/optional/field.field.node.forum.body.yml @@ -18,4 +18,5 @@ default_value: { } default_value_callback: '' settings: display_summary: true + allowed_formats: { } field_type: text_with_summary diff --git a/core/modules/node/node.module b/core/modules/node/node.module index aade3e8..4f06b0e 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 83cea4f..1063a94 100644 --- a/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php +++ b/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php @@ -7,12 +7,36 @@ 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'], + '#description' => t('Select the allowed text formats. If no formats are selected, all available text formats will be displayed to the user.'), + ]; + + 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 d42e3a7..d24357b 100644 --- a/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php +++ b/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php @@ -85,7 +85,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 25bb627..88b0a94 100644 --- a/core/modules/text/src/Plugin/Field/FieldWidget/TextareaWidget.php +++ b/core/modules/text/src/Plugin/Field/FieldWidget/TextareaWidget.php @@ -25,11 +25,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 5a3ed05..8d4cd03 100644 --- a/core/modules/text/src/Plugin/Field/FieldWidget/TextfieldWidget.php +++ b/core/modules/text/src/Plugin/Field/FieldWidget/TextfieldWidget.php @@ -25,11 +25,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 993346a..3e6aa51 100644 --- a/core/modules/text/src/Tests/TextFieldTest.php +++ b/core/modules/text/src/Tests/TextFieldTest.php @@ -142,6 +142,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) { @@ -182,8 +253,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/tests/src/Kernel/Entity/ViewEntityDependenciesTest.php b/core/modules/views/tests/src/Kernel/Entity/ViewEntityDependenciesTest.php index f97659a..72a42bc 100644 --- a/core/modules/views/tests/src/Kernel/Entity/ViewEntityDependenciesTest.php +++ b/core/modules/views/tests/src/Kernel/Entity/ViewEntityDependenciesTest.php @@ -74,7 +74,10 @@ protected function setUp($import_test_views = TRUE) { '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 89118ef..8f00859 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,4 +18,5 @@ default_value: { } default_value_callback: '' settings: display_summary: false + allowed_formats: { } 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 1337070..8d97e03 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,5 +16,6 @@ required: true translatable: true default_value: { } default_value_callback: '' -settings: { } +settings: + allowed_formats: { } 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 8f3681d..9ac4f52 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,4 +18,5 @@ default_value: { } default_value_callback: '' settings: display_summary: true + allowed_formats: { } 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 6c09432..8ecd103 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,4 +18,5 @@ default_value: { } default_value_callback: '' settings: display_summary: true + allowed_formats: { } field_type: text_with_summary