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.
|
||||
foreach ($definitions as $id => $definition) {
|
||||
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] = [
|
||||
'label' => $option['label'],
|
||||
] + $definition;
|
||||
|
@ -150,6 +150,19 @@ class FieldTypePluginManager extends DefaultPluginManager implements FieldTypePl
|
|||
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}
|
||||
*/
|
||||
|
|
|
@ -84,6 +84,26 @@ interface FieldTypePluginManagerInterface extends PluginManagerInterface, Catego
|
|||
*/
|
||||
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.
|
||||
*
|
||||
|
|
|
@ -16,6 +16,11 @@ interface PreconfiguredFieldUiOptionsInterface {
|
|||
/**
|
||||
* 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[][]
|
||||
* A multi-dimensional array with string keys and the following structure:
|
||||
* - 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\FieldConfig
|
||||
* @see \Drupal\Core\Entity\Display\EntityDisplayInterface::setComponent()
|
||||
* @see \Drupal\Core\Field\FieldTypePluginManagerInterface::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.
|
||||
*
|
||||
|
|
|
@ -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,
|
||||
];
|
||||
$widget_id = $formatter_id = NULL;
|
||||
$widget_settings = $formatter_settings = [];
|
||||
|
||||
// Check if we're dealing with a preconfigured field.
|
||||
if (strpos($field_storage_values['type'], 'field_ui:') !== FALSE) {
|
||||
list(, $field_type, $option_key) = explode(':', $field_storage_values['type'], 3);
|
||||
$field_storage_values['type'] = $field_type;
|
||||
|
||||
$field_type_class = $this->fieldTypePluginManager->getDefinition($field_type)['class'];
|
||||
$field_options = $field_type_class::getPreconfiguredOptions()[$option_key];
|
||||
$field_definition = $this->fieldTypePluginManager->getDefinition($field_type);
|
||||
$options = $this->fieldTypePluginManager->getPreconfiguredOptions($field_definition['id']);
|
||||
$field_options = $options[$option_key];
|
||||
|
||||
// Merge in preconfigured field storage options.
|
||||
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_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_settings = isset($field_options['entity_view_display']['settings']) ? $field_options['entity_view_display']['settings'] : [];
|
||||
}
|
||||
|
||||
// Create the field storage and field.
|
||||
|
@ -349,8 +353,8 @@ class FieldStorageAddForm extends FormBase {
|
|||
$field = $this->entityManager->getStorage('field_config')->create($field_values);
|
||||
$field->save();
|
||||
|
||||
$this->configureEntityFormDisplay($values['field_name'], $widget_id);
|
||||
$this->configureEntityViewDisplay($values['field_name'], $formatter_id);
|
||||
$this->configureEntityFormDisplay($values['field_name'], $widget_id, $widget_settings);
|
||||
$this->configureEntityViewDisplay($values['field_name'], $formatter_id, $formatter_settings);
|
||||
|
||||
// Always show the field settings step, as the cardinality needs to be
|
||||
// configured for new fields.
|
||||
|
@ -418,12 +422,20 @@ class FieldStorageAddForm extends FormBase {
|
|||
* The field name.
|
||||
* @param string|null $widget_id
|
||||
* (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
|
||||
// default widget and settings). It stays hidden for other form modes
|
||||
// until it is explicitly configured.
|
||||
$options = $widget_id ? ['type' => $widget_id] : [];
|
||||
entity_get_form_display($this->entityTypeId, $this->bundle, 'default')
|
||||
->setComponent($field_name, $options)
|
||||
->save();
|
||||
|
@ -436,12 +448,20 @@ class FieldStorageAddForm extends FormBase {
|
|||
* The field name.
|
||||
* @param string|null $formatter_id
|
||||
* (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
|
||||
// default formatter and settings). It stays hidden for other view
|
||||
// modes until it is explicitly configured.
|
||||
$options = $formatter_id ? ['type' => $formatter_id] : [];
|
||||
entity_get_display($this->entityTypeId, $this->bundle, 'default')
|
||||
->setComponent($field_name, $options)
|
||||
->save();
|
||||
|
|
|
@ -750,6 +750,7 @@ class ManageFieldsTest extends WebTestBase {
|
|||
$this->assertEqual($form_display->getComponent('field_test_custom_options')['type'], 'test_field_widget_multiple');
|
||||
$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')['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];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 node fields',
|
||||
'administer node form display',
|
||||
'administer node display',
|
||||
'bypass node access',
|
||||
];
|
||||
|
||||
|
|
|
@ -175,4 +175,21 @@ class MediaUiFunctionalTest extends MediaFunctionalTestBase {
|
|||
$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