Issue #2928699 by marcoscano, phenaproxima, amateescu, seanB, yoroy: Add an alter hook for the pre-configured field UI options and implement it in the Media module
parent
72c76b73c5
commit
cf805af249
|
@ -135,7 +135,7 @@ class FieldTypePluginManager extends DefaultPluginManager implements FieldTypePl
|
||||||
// Add preconfigured definitions.
|
// Add preconfigured definitions.
|
||||||
foreach ($definitions as $id => $definition) {
|
foreach ($definitions as $id => $definition) {
|
||||||
if (is_subclass_of($definition['class'], '\Drupal\Core\Field\PreconfiguredFieldUiOptionsInterface')) {
|
if (is_subclass_of($definition['class'], '\Drupal\Core\Field\PreconfiguredFieldUiOptionsInterface')) {
|
||||||
foreach ($definition['class']::getPreconfiguredOptions() as $key => $option) {
|
foreach ($this->getPreconfiguredOptions($definition['id']) as $key => $option) {
|
||||||
$definitions['field_ui:' . $id . ':' . $key] = [
|
$definitions['field_ui:' . $id . ':' . $key] = [
|
||||||
'label' => $option['label'],
|
'label' => $option['label'],
|
||||||
] + $definition;
|
] + $definition;
|
||||||
|
@ -150,6 +150,19 @@ class FieldTypePluginManager extends DefaultPluginManager implements FieldTypePl
|
||||||
return $definitions;
|
return $definitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getPreconfiguredOptions($field_type) {
|
||||||
|
$options = [];
|
||||||
|
$class = $this->getPluginClass($field_type);
|
||||||
|
if (is_subclass_of($class, '\Drupal\Core\Field\PreconfiguredFieldUiOptionsInterface')) {
|
||||||
|
$options = $class::getPreconfiguredOptions();
|
||||||
|
$this->moduleHandler->alter('field_ui_preconfigured_options', $options, $field_type);
|
||||||
|
}
|
||||||
|
return $options;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -84,6 +84,26 @@ interface FieldTypePluginManagerInterface extends PluginManagerInterface, Catego
|
||||||
*/
|
*/
|
||||||
public function getUiDefinitions();
|
public function getUiDefinitions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns preconfigured field options for a field type.
|
||||||
|
*
|
||||||
|
* This is a wrapper around
|
||||||
|
* \Drupal\Core\Field\PreconfiguredFieldUiOptionsInterface::getPreconfiguredOptions()
|
||||||
|
* allowing modules to alter the result of this method by implementing
|
||||||
|
* hook_field_ui_preconfigured_options_alter().
|
||||||
|
*
|
||||||
|
* @param string $field_type
|
||||||
|
* The field type plugin ID.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* A multi-dimensional array as returned from
|
||||||
|
* \Drupal\Core\Field\PreconfiguredFieldUiOptionsInterface::getPreconfiguredOptions().
|
||||||
|
*
|
||||||
|
* @see \Drupal\Core\Field\PreconfiguredFieldUiOptionsInterface::getPreconfiguredOptions()
|
||||||
|
* @see hook_field_ui_preconfigured_options_alter()
|
||||||
|
*/
|
||||||
|
public function getPreconfiguredOptions($field_type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the PHP class that implements the field type plugin.
|
* Returns the PHP class that implements the field type plugin.
|
||||||
*
|
*
|
||||||
|
|
|
@ -16,6 +16,11 @@ interface PreconfiguredFieldUiOptionsInterface {
|
||||||
/**
|
/**
|
||||||
* Returns preconfigured field options for a field type.
|
* Returns preconfigured field options for a field type.
|
||||||
*
|
*
|
||||||
|
* Note that if you want to give modules an opportunity to alter the result
|
||||||
|
* of this method, you should call
|
||||||
|
* \Drupal\Core\Field\FieldTypePluginManagerInterface::getPreconfiguredOptions()
|
||||||
|
* instead.
|
||||||
|
*
|
||||||
* @return mixed[][]
|
* @return mixed[][]
|
||||||
* A multi-dimensional array with string keys and the following structure:
|
* A multi-dimensional array with string keys and the following structure:
|
||||||
* - label: The label to show in the field type selection list.
|
* - label: The label to show in the field type selection list.
|
||||||
|
@ -35,6 +40,7 @@ interface PreconfiguredFieldUiOptionsInterface {
|
||||||
* @see \Drupal\field\Entity\FieldStorageConfig
|
* @see \Drupal\field\Entity\FieldStorageConfig
|
||||||
* @see \Drupal\field\Entity\FieldConfig
|
* @see \Drupal\field\Entity\FieldConfig
|
||||||
* @see \Drupal\Core\Entity\Display\EntityDisplayInterface::setComponent()
|
* @see \Drupal\Core\Entity\Display\EntityDisplayInterface::setComponent()
|
||||||
|
* @see \Drupal\Core\Field\FieldTypePluginManagerInterface::getPreconfiguredOptions()
|
||||||
*/
|
*/
|
||||||
public static function getPreconfiguredOptions();
|
public static function getPreconfiguredOptions();
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,33 @@ function hook_field_info_alter(&$info) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform alterations on preconfigured field options.
|
||||||
|
*
|
||||||
|
* @param array $options
|
||||||
|
* Array of options as returned from
|
||||||
|
* \Drupal\Core\Field\PreconfiguredFieldUiOptionsInterface::getPreconfiguredOptions().
|
||||||
|
* @param string $field_type
|
||||||
|
* The field type plugin ID.
|
||||||
|
*
|
||||||
|
* @see \Drupal\Core\Field\PreconfiguredFieldUiOptionsInterface::getPreconfiguredOptions()
|
||||||
|
*/
|
||||||
|
function hook_field_ui_preconfigured_options_alter(array &$options, $field_type) {
|
||||||
|
// If the field is not an "entity_reference"-based field, bail out.
|
||||||
|
/** @var \Drupal\Core\Field\FieldTypePluginManager $field_type_manager */
|
||||||
|
$field_type_manager = \Drupal::service('plugin.manager.field.field_type');
|
||||||
|
$class = $field_type_manager->getPluginClass($field_type);
|
||||||
|
if (!is_a($class, 'Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem', TRUE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the default formatter for media in entity reference fields to be the
|
||||||
|
// "Rendered entity" formatter.
|
||||||
|
if (!empty($options['media'])) {
|
||||||
|
$options['media']['entity_view_display']['type'] = 'entity_reference_entity_view';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forbid a field storage update from occurring.
|
* Forbid a field storage update from occurring.
|
||||||
*
|
*
|
||||||
|
|
|
@ -171,3 +171,14 @@ function field_test_entity_bundle_field_info_alter(&$fields, EntityTypeInterface
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements hook_field_ui_preconfigured_options_alter().
|
||||||
|
*/
|
||||||
|
function field_test_field_ui_preconfigured_options_alter(array &$options, $field_type) {
|
||||||
|
if ($field_type === 'test_field_with_preconfigured_options') {
|
||||||
|
$options['custom_options']['entity_view_display']['settings'] = [
|
||||||
|
'test_formatter_setting_multiple' => 'altered dummy test string',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -312,14 +312,16 @@ class FieldStorageAddForm extends FormBase {
|
||||||
'translatable' => FALSE,
|
'translatable' => FALSE,
|
||||||
];
|
];
|
||||||
$widget_id = $formatter_id = NULL;
|
$widget_id = $formatter_id = NULL;
|
||||||
|
$widget_settings = $formatter_settings = [];
|
||||||
|
|
||||||
// Check if we're dealing with a preconfigured field.
|
// Check if we're dealing with a preconfigured field.
|
||||||
if (strpos($field_storage_values['type'], 'field_ui:') !== FALSE) {
|
if (strpos($field_storage_values['type'], 'field_ui:') !== FALSE) {
|
||||||
list(, $field_type, $option_key) = explode(':', $field_storage_values['type'], 3);
|
list(, $field_type, $option_key) = explode(':', $field_storage_values['type'], 3);
|
||||||
$field_storage_values['type'] = $field_type;
|
$field_storage_values['type'] = $field_type;
|
||||||
|
|
||||||
$field_type_class = $this->fieldTypePluginManager->getDefinition($field_type)['class'];
|
$field_definition = $this->fieldTypePluginManager->getDefinition($field_type);
|
||||||
$field_options = $field_type_class::getPreconfiguredOptions()[$option_key];
|
$options = $this->fieldTypePluginManager->getPreconfiguredOptions($field_definition['id']);
|
||||||
|
$field_options = $options[$option_key];
|
||||||
|
|
||||||
// Merge in preconfigured field storage options.
|
// Merge in preconfigured field storage options.
|
||||||
if (isset($field_options['field_storage_config'])) {
|
if (isset($field_options['field_storage_config'])) {
|
||||||
|
@ -340,7 +342,9 @@ class FieldStorageAddForm extends FormBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
$widget_id = isset($field_options['entity_form_display']['type']) ? $field_options['entity_form_display']['type'] : NULL;
|
$widget_id = isset($field_options['entity_form_display']['type']) ? $field_options['entity_form_display']['type'] : NULL;
|
||||||
|
$widget_settings = isset($field_options['entity_form_display']['settings']) ? $field_options['entity_form_display']['settings'] : [];
|
||||||
$formatter_id = isset($field_options['entity_view_display']['type']) ? $field_options['entity_view_display']['type'] : NULL;
|
$formatter_id = isset($field_options['entity_view_display']['type']) ? $field_options['entity_view_display']['type'] : NULL;
|
||||||
|
$formatter_settings = isset($field_options['entity_view_display']['settings']) ? $field_options['entity_view_display']['settings'] : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the field storage and field.
|
// Create the field storage and field.
|
||||||
|
@ -349,8 +353,8 @@ class FieldStorageAddForm extends FormBase {
|
||||||
$field = $this->entityManager->getStorage('field_config')->create($field_values);
|
$field = $this->entityManager->getStorage('field_config')->create($field_values);
|
||||||
$field->save();
|
$field->save();
|
||||||
|
|
||||||
$this->configureEntityFormDisplay($values['field_name'], $widget_id);
|
$this->configureEntityFormDisplay($values['field_name'], $widget_id, $widget_settings);
|
||||||
$this->configureEntityViewDisplay($values['field_name'], $formatter_id);
|
$this->configureEntityViewDisplay($values['field_name'], $formatter_id, $formatter_settings);
|
||||||
|
|
||||||
// Always show the field settings step, as the cardinality needs to be
|
// Always show the field settings step, as the cardinality needs to be
|
||||||
// configured for new fields.
|
// configured for new fields.
|
||||||
|
@ -418,12 +422,20 @@ class FieldStorageAddForm extends FormBase {
|
||||||
* The field name.
|
* The field name.
|
||||||
* @param string|null $widget_id
|
* @param string|null $widget_id
|
||||||
* (optional) The plugin ID of the widget. Defaults to NULL.
|
* (optional) The plugin ID of the widget. Defaults to NULL.
|
||||||
|
* @param array $widget_settings
|
||||||
|
* (optional) An array of widget settings. Defaults to an empty array.
|
||||||
*/
|
*/
|
||||||
protected function configureEntityFormDisplay($field_name, $widget_id = NULL) {
|
protected function configureEntityFormDisplay($field_name, $widget_id = NULL, array $widget_settings = []) {
|
||||||
|
$options = [];
|
||||||
|
if ($widget_id) {
|
||||||
|
$options['type'] = $widget_id;
|
||||||
|
if (!empty($widget_settings)) {
|
||||||
|
$options['settings'] = $widget_settings;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Make sure the field is displayed in the 'default' form mode (using
|
// Make sure the field is displayed in the 'default' form mode (using
|
||||||
// default widget and settings). It stays hidden for other form modes
|
// default widget and settings). It stays hidden for other form modes
|
||||||
// until it is explicitly configured.
|
// until it is explicitly configured.
|
||||||
$options = $widget_id ? ['type' => $widget_id] : [];
|
|
||||||
entity_get_form_display($this->entityTypeId, $this->bundle, 'default')
|
entity_get_form_display($this->entityTypeId, $this->bundle, 'default')
|
||||||
->setComponent($field_name, $options)
|
->setComponent($field_name, $options)
|
||||||
->save();
|
->save();
|
||||||
|
@ -436,12 +448,20 @@ class FieldStorageAddForm extends FormBase {
|
||||||
* The field name.
|
* The field name.
|
||||||
* @param string|null $formatter_id
|
* @param string|null $formatter_id
|
||||||
* (optional) The plugin ID of the formatter. Defaults to NULL.
|
* (optional) The plugin ID of the formatter. Defaults to NULL.
|
||||||
|
* @param array $formatter_settings
|
||||||
|
* (optional) An array of formatter settings. Defaults to an empty array.
|
||||||
*/
|
*/
|
||||||
protected function configureEntityViewDisplay($field_name, $formatter_id = NULL) {
|
protected function configureEntityViewDisplay($field_name, $formatter_id = NULL, array $formatter_settings = []) {
|
||||||
|
$options = [];
|
||||||
|
if ($formatter_id) {
|
||||||
|
$options['type'] = $formatter_id;
|
||||||
|
if (!empty($formatter_settings)) {
|
||||||
|
$options['settings'] = $formatter_settings;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Make sure the field is displayed in the 'default' view mode (using
|
// Make sure the field is displayed in the 'default' view mode (using
|
||||||
// default formatter and settings). It stays hidden for other view
|
// default formatter and settings). It stays hidden for other view
|
||||||
// modes until it is explicitly configured.
|
// modes until it is explicitly configured.
|
||||||
$options = $formatter_id ? ['type' => $formatter_id] : [];
|
|
||||||
entity_get_display($this->entityTypeId, $this->bundle, 'default')
|
entity_get_display($this->entityTypeId, $this->bundle, 'default')
|
||||||
->setComponent($field_name, $options)
|
->setComponent($field_name, $options)
|
||||||
->save();
|
->save();
|
||||||
|
|
|
@ -750,6 +750,7 @@ class ManageFieldsTest extends WebTestBase {
|
||||||
$this->assertEqual($form_display->getComponent('field_test_custom_options')['type'], 'test_field_widget_multiple');
|
$this->assertEqual($form_display->getComponent('field_test_custom_options')['type'], 'test_field_widget_multiple');
|
||||||
$view_display = entity_get_display('node', 'article', 'default');
|
$view_display = entity_get_display('node', 'article', 'default');
|
||||||
$this->assertEqual($view_display->getComponent('field_test_custom_options')['type'], 'field_test_multiple');
|
$this->assertEqual($view_display->getComponent('field_test_custom_options')['type'], 'field_test_multiple');
|
||||||
|
$this->assertEqual($view_display->getComponent('field_test_custom_options')['settings']['test_formatter_setting_multiple'], 'altered dummy test string');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -96,3 +96,22 @@ function template_preprocess_media(array &$variables) {
|
||||||
$variables['content'][$key] = $variables['elements'][$key];
|
$variables['content'][$key] = $variables['elements'][$key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements hook_field_ui_preconfigured_options_alter().
|
||||||
|
*/
|
||||||
|
function media_field_ui_preconfigured_options_alter(array &$options, $field_type) {
|
||||||
|
// If the field is not an "entity_reference"-based field, bail out.
|
||||||
|
/** @var \Drupal\Core\Field\FieldTypePluginManager $field_type_manager */
|
||||||
|
$field_type_manager = \Drupal::service('plugin.manager.field.field_type');
|
||||||
|
$class = $field_type_manager->getPluginClass($field_type);
|
||||||
|
if (!is_a($class, 'Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem', TRUE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the default formatter for media in entity reference fields to be the
|
||||||
|
// "Rendered entity" formatter.
|
||||||
|
if (!empty($options['media'])) {
|
||||||
|
$options['media']['entity_view_display']['type'] = 'entity_reference_entity_view';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ trait MediaFunctionalTestTrait {
|
||||||
'administer content types',
|
'administer content types',
|
||||||
'administer node fields',
|
'administer node fields',
|
||||||
'administer node form display',
|
'administer node form display',
|
||||||
|
'administer node display',
|
||||||
'bypass node access',
|
'bypass node access',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -175,4 +175,21 @@ class MediaUiFunctionalTest extends MediaFunctionalTestBase {
|
||||||
$assert_session->pageTextContains($second_media_item->getName());
|
$assert_session->pageTextContains($second_media_item->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that media in ER fields use the Rendered Entity formatter by default.
|
||||||
|
*/
|
||||||
|
public function testRenderedEntityReferencedMedia() {
|
||||||
|
$page = $this->getSession()->getPage();
|
||||||
|
$assert_session = $this->assertSession();
|
||||||
|
|
||||||
|
$this->drupalCreateContentType(['type' => 'page', 'name' => 'Page']);
|
||||||
|
$this->drupalGet('/admin/structure/types/manage/page/fields/add-field');
|
||||||
|
$page->selectFieldOption('new_storage_type', 'field_ui:entity_reference:media');
|
||||||
|
$page->fillField('label', 'Foo field');
|
||||||
|
$page->fillField('field_name', 'foo_field');
|
||||||
|
$page->pressButton('Save and continue');
|
||||||
|
$this->drupalGet('/admin/structure/types/manage/page/display');
|
||||||
|
$assert_session->fieldValueEquals('fields[field_foo_field][type]', 'entity_reference_entity_view');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue