Commit 48bf0252 authored by catch's avatar catch

Issue #2005434 by alexpott, heddn, andrewmacpherson, swentel: Let 3rd party...

Issue #2005434 by alexpott, heddn, andrewmacpherson, swentel: Let 3rd party modules store extra configuration in EntityDisplay.
parent c9ebb49c
......@@ -91,6 +91,8 @@ public function isDisplayConfigurable($display_context);
* for the field type will be used.
* - settings: (array) Settings for the plugin specified above. The default
* settings for the plugin will be used for settings left unspecified.
* - third_party_settings: (array) Settings provided by other extensions
* through hook_field_formatter_third_party_settings_form().
* - weight: (float) The weight of the element. Not needed if 'type' is
* 'hidden'.
* The defaults of the various display options above get applied by the used
......
......@@ -55,14 +55,17 @@ abstract class FormatterBase extends PluginSettingsBase implements FormatterInte
* The formatter label display setting.
* @param string $view_mode
* The view mode.
* @param array $third_party_settings
* Any third party settings settings.
*/
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode) {
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings) {
parent::__construct(array(), $plugin_id, $plugin_definition);
$this->fieldDefinition = $field_definition;
$this->settings = $settings;
$this->label = $label;
$this->viewMode = $view_mode;
$this->thirdPartySettings = $third_party_settings;
}
/**
......
......@@ -68,7 +68,7 @@ public function createInstance($plugin_id, array $configuration = array()) {
return $plugin_class::create(\Drupal::getContainer(), $configuration, $plugin_id, $plugin_definition);
}
return new $plugin_class($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings'], $configuration['label'], $configuration['view_mode']);
return new $plugin_class($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings'], $configuration['label'], $configuration['view_mode'], $configuration['third_party_settings']);
}
/**
......@@ -91,6 +91,8 @@ public function createInstance($plugin_id, array $configuration = array()) {
* also be used if the requested formatter is not available.
* - settings: (array) Settings specific to the formatter. Each setting
* defaults to the default value specified in the formatter definition.
* - third_party_settings: (array) Settings provided by other extensions
* through hook_field_formatter_third_party_settings_form().
*
* @return \Drupal\Core\Field\FormatterInterface|null
* A formatter object or NULL when plugin is not found.
......@@ -143,6 +145,7 @@ public function prepareConfiguration($field_type, array $configuration) {
$configuration += array(
'label' => 'above',
'settings' => array(),
'third_party_settings' => array(),
);
// If no formatter is specified, use the default formatter.
if (!isset($configuration['type'])) {
......
......@@ -23,6 +23,15 @@ abstract class PluginSettingsBase extends PluginBase implements PluginSettingsIn
*/
protected $settings = array();
/**
* The plugin settings injected by third party modules.
*
* @see hooks
*
* @var array
*/
protected $thirdPartySettings = array();
/**
* Whether default settings have been merged into the current $settings.
*
......@@ -84,4 +93,19 @@ public function setSetting($key, $value) {
return $this;
}
/**
* {@inheritdoc}
*/
public function getThirdPartySetting($module, $key, $default = NULL) {
return isset($this->thirdPartySettings[$module][$key]) ? $this->thirdPartySettings[$module][$key] : $default;
}
/**
* {@inheritdoc}
*/
public function setThirdPartySetting($module, $key, $value) {
$this->thirdPartySettings[$module][$key] = $value;
return $this;
}
}
......@@ -64,4 +64,35 @@ public function setSettings(array $settings);
*/
public function setSetting($key, $value);
/**
* Returns the value of a third-party setting, or $default if not set.
*
* @param string $module
* The module providing the third-party setting.
* @param string $key
* The setting name.
* @param mixed $default
* (optional) The default value if the third party setting is not set.
* Defaults to NULL.
*
* @return mixed|NULL
* The setting value. Returns NULL if the setting does not exist and
* $default is not provided.
*/
public function getThirdPartySetting($module, $key, $default = NULL);
/**
* Sets the value of a third-party setting for the plugin.
*
* @param string $module
* The module providing the third-party setting.
* @param string $key
* The setting name.
* @param mixed $value
* The setting value.
*
* @return $this
*/
public function setThirdPartySetting($module, $key, $value);
}
......@@ -43,11 +43,14 @@ abstract class WidgetBase extends PluginSettingsBase implements WidgetInterface
* The definition of the field to which the widget is associated.
* @param array $settings
* The widget settings.
* @param array $third_party_settings
* Any third party settings settings.
*/
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings) {
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings) {
parent::__construct(array(), $plugin_id, $plugin_definition);
$this->fieldDefinition = $field_definition;
$this->settings = $settings;
$this->thirdPartySettings = $third_party_settings;
}
/**
......
......@@ -71,6 +71,8 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac
* used if the requested widget is not available.
* - settings: (array) Settings specific to the widget. Each setting
* defaults to the default value specified in the widget definition.
* - third_party_settings: (array) Settings provided by other extensions
* through hook_field_formatter_third_party_settings_form().
*
* @return \Drupal\Core\Field\WidgetInterface|null
* A Widget object or NULL when plugin is not found.
......@@ -124,7 +126,7 @@ public function createInstance($plugin_id, array $configuration = array()) {
return $plugin_class::create(\Drupal::getContainer(), $configuration, $plugin_id, $plugin_definition);
}
return new $plugin_class($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings']);
return new $plugin_class($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings'], $configuration['third_party_settings']);
}
......@@ -143,6 +145,7 @@ public function prepareConfiguration($field_type, array $configuration) {
// Fill in defaults for missing properties.
$configuration += array(
'settings' => array(),
'third_party_settings' => array(),
);
// If no widget is specified, use the default widget.
if (!isset($configuration['type'])) {
......
......@@ -75,6 +75,7 @@ public static function create(ContainerInterface $container, array $configuratio
$configuration['settings'],
$configuration['label'],
$configuration['view_mode'],
$configuration['third_party_settings'],
$container->get('current_user'),
$container->get('entity.manager')->getStorage('comment'),
$container->get('entity.manager')->getViewBuilder('comment')
......@@ -96,6 +97,8 @@ public static function create(ContainerInterface $container, array $configuratio
* The formatter label display setting.
* @param string $view_mode
* The view mode.
* @param array $third_party_settings
* Third party settings.
* @param \Drupal\Core\Session\AccountInterface $current_user
* The current user.
* @param \Drupal\comment\CommentStorageInterface $comment_storage
......@@ -103,8 +106,8 @@ public static function create(ContainerInterface $container, array $configuratio
* @param \Drupal\Core\Entity\EntityViewBuilderInterface $comment_view_builder
* The comment view builder.
*/
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, AccountInterface $current_user, CommentStorageInterface $comment_storage, EntityViewBuilderInterface $comment_view_builder) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode);
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, AccountInterface $current_user, CommentStorageInterface $comment_storage, EntityViewBuilderInterface $comment_view_builder) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
$this->viewBuilder = $comment_view_builder;
$this->storage = $comment_storage;
$this->currentUser = $current_user;
......
......@@ -67,13 +67,15 @@ public static function defaultSettings() {
* The formatter label display setting.
* @param string $view_mode
* The view mode.
* @param array $third_party_settings
* Third party settings.
* @param \Drupal\Core\Datetime\Date $date_service
* The date service.
* @param \Drupal\Core\Entity\EntityStorageInterface $date_storage
* The date storage.
*/
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, Date $date_service, EntityStorageInterface $date_storage) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode);
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, Date $date_service, EntityStorageInterface $date_storage) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
$this->dateService = $date_service;
$this->dateStorage = $date_storage;
......@@ -90,6 +92,7 @@ public static function create(ContainerInterface $container, array $configuratio
$configuration['settings'],
$configuration['label'],
$configuration['view_mode'],
$configuration['third_party_settings'],
$container->get('date'),
$container->get('entity.manager')->getStorage('date_format')
);
......
......@@ -34,8 +34,8 @@ class DateTimeDefaultWidget extends WidgetBase {
/**
* {@inheritdoc}
*/
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings);
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);
// @todo Inject this once https://drupal.org/node/2035317 is in.
$this->dateStorage = \Drupal::entityManager()->getStorage('date_format');
......
......@@ -4,15 +4,20 @@
entity_field_view_display_base:
type: mapping
mapping:
label:
type: string
label: 'Label setting machine name'
type:
type: string
label: 'Format type machine name'
weight:
type: integer
label: 'Weight'
third_party_settings:
type: sequence
label: 'Third party settings'
sequence:
- type: entity_view_display.third_party.[%key]
label:
type: string
label: 'Label setting machine name'
# Schema for the base of the form mode display format settings.
entity_field_form_display_base:
......@@ -24,3 +29,8 @@ entity_field_form_display_base:
weight:
type: integer
label: 'Weight'
third_party_settings:
type: sequence
label: 'Third party settings'
sequence:
- type: entity_form_display.third_party.[%key]
......@@ -115,27 +115,13 @@ entity.form_display.*.*.*:
# Default schema for entity display field with undefined type.
entity_view_display.field.*:
type: mapping
type: entity_field_view_display_base
label: 'Entity display default'
mapping:
visible:
type: boolean
label: 'Visibility'
weight:
type: integer
label: 'Weight'
# Default schema for entity form display field with undefined type.
entity_form_display.field.*:
type: mapping
type: entity_field_form_display_base
label: 'Entity form display default'
mapping:
visible:
type: boolean
label: 'Visibility'
weight:
type: integer
label: 'Weight'
entity_form_display.field.string:
type: entity_field_form_display_base
......
......@@ -177,6 +177,12 @@ public function calculateDependencies() {
if (isset($component['type']) && $definition = $this->pluginManager->getDefinition($component['type'], FALSE)) {
$this->addDependency('module', $definition['provider']);
}
// Create dependencies on any modules providing third party settings.
if (isset($component['third_party_settings'])) {
foreach($component['third_party_settings'] as $module => $settings) {
$this->addDependency('module', $module);
}
}
}
// Depend on configured modes.
if ($this->mode != 'default') {
......
......@@ -69,6 +69,7 @@ public function testEntityDisplayCRUD() {
'type' => 'string',
'weight' => -5,
'settings' => array(),
'third_party_settings' => array(),
);
$this->assertEqual($display->getComponents(), $expected);
......@@ -174,6 +175,7 @@ public function testFieldComponent() {
'label' => 'above',
'type' => $default_formatter,
'settings' => $formatter_settings,
'third_party_settings' => array(),
);
$this->assertEqual($display->getComponent($field_name), $expected);
......@@ -221,12 +223,14 @@ public function testBaseFieldComponent() {
'label' => 'above',
'type' => 'text_default',
'settings' => $formatter_settings,
'third_party_settings' => array(),
'weight' => 10,
),
'test_display_non_configurable' => array(
'label' => 'above',
'type' => 'text_default',
'settings' => $formatter_settings,
'third_party_settings' => array(),
'weight' => 11,
),
);
......
......@@ -84,6 +84,7 @@ public function testFieldComponent() {
'weight' => 0,
'type' => $default_widget,
'settings' => $widget_settings,
'third_party_settings' => array(),
);
$this->assertEqual($form_display->getComponent($field_name), $expected);
......@@ -136,11 +137,13 @@ public function testBaseFieldComponent() {
'test_display_configurable' => array(
'type' => 'text_textfield',
'settings' => $formatter_settings,
'third_party_settings' => array(),
'weight' => 10,
),
'test_display_non_configurable' => array(
'type' => 'text_textfield',
'settings' => $formatter_settings,
'third_party_settings' => array(),
'weight' => 11,
),
);
......
entity_view_display.field.field_test_multiple:
type: entity_field_view_display_base
label: 'field_test display format settings'
mapping:
settings:
type: mapping
label: 'Settings'
mapping:
test_formatter_setting_multiple:
type: string
label: 'Test setting'
entity_form_display.field.test_field_widget_multiple:
type: entity_field_form_display_base
label: 'field_test display format settings'
mapping:
settings:
type: mapping
label: 'Settings'
mapping:
test_widget_setting_multiple:
type: string
label: 'Test setting'
......@@ -155,44 +155,6 @@ function field_test_query_efq_metadata_test_alter(&$query) {
$efq_test_metadata = $query->getMetadata('foo');
}
/**
* Implements hook_field_widget_settings_form_alter().
*/
function field_test_field_widget_settings_form_alter(&$element, &$form_state, $context) {
$element['field_test_widget_settings_form_alter'] = array(
'#type' => 'textfield',
'#title' => t('Widget settings form alter'),
'#default_value' => $context['widget']->getSetting('field_test_widget_settings_form_alter'),
);
}
/**
* Implements hook_field_widget_settings_summary_alter().
*/
function field_test_field_widget_settings_summary_alter(&$summary, $context) {
$summary[] = 'field_test_field_widget_settings_summary_alter';
return $summary;
}
/**
* Implements hook_field_formatter_settings_form_alter().
*/
function field_test_field_formatter_settings_form_alter(&$element, &$form_state, $context) {
$element['field_test_formatter_settings_form_alter'] = array(
'#type' => 'textfield',
'#title' => t('Formatter settings form alter'),
'#default_value' => $context['formatter']->getSetting('field_test_formatter_settings_form_alter'),
);
}
/**
* Implements hook_field_formatter_settings_summary_alter().
*/
function field_test_field_formatter_settings_summary_alter(&$summary, $context) {
$summary[] = 'field_test_field_formatter_settings_summary_alter';
return $summary;
}
/**
* Implements hook_entity_extra_field_info_alter().
*/
......
entity_view_display.third_party.field_third_party_test:
type: mapping
label: 'field_third_party_test entity display settings'
mapping:
field_test_field_formatter_third_party_settings_form:
type: string
label: field_test_field_formatter_third_party_settings_form
entity_form_display.third_party.field_third_party_test:
type: mapping
label: 'field_third_party_test entity form display settings'
mapping:
field_test_widget_third_party_settings_form:
type: string
label: field_test_widget_third_party_settings_form
name: 'Field Third Party Settings Test'
type: module
description: 'Support module for the Field API tests.'
core: 8.x
package: Testing
version: VERSION
dependencies:
- entity_test
- field_test
<?php
/**
* Implements hook_field_widget_third_party_settings_form().
*/
function field_third_party_test_field_widget_third_party_settings_form(\Drupal\Core\Field\WidgetInterface $plugin, \Drupal\Core\Field\FieldDefinitionInterface $field_definition, $form_mode, $form, $form_state) {
$element['field_test_widget_third_party_settings_form'] = array(
'#type' => 'textfield',
'#title' => t('3rd party widget settings form'),
'#default_value' => $plugin->getThirdPartySetting('field_third_party_test', 'field_test_widget_third_party_settings_form'),
);
return $element;
}
/**
* Implements hook_field_widget_settings_summary_alter().
*/
function field_third_party_test_field_widget_settings_summary_alter(&$summary, $context) {
$summary[] = 'field_test_field_widget_settings_summary_alter';
return $summary;
}
/**
* Implements hook_field_formatter_third_party_settings_form().
*/
function field_third_party_test_field_formatter_third_party_settings_form(\Drupal\Core\Field\FormatterInterface $plugin, \Drupal\Core\Field\FieldDefinitionInterface $field_definition, $view_mode, $form, $form_state) {
$element['field_test_field_formatter_third_party_settings_form'] = array(
'#type' => 'textfield',
'#title' => t('3rd party formatter settings form'),
'#default_value' => $plugin->getThirdPartySetting('field_third_party_test', 'field_test_field_formatter_third_party_settings_form'),
);
return $element;
}
/**
* Implements hook_field_formatter_settings_summary_alter().
*/
function field_third_party_test_field_formatter_settings_summary_alter(&$summary, $context) {
$summary[] = 'field_test_field_formatter_settings_summary_alter';
return $summary;
}
......@@ -11,65 +11,76 @@
*/
/**
* Alters the formatter settings form.
* Allow modules to add settings to field formatters provided by other modules.
*
* @param $element
* Form array.
* @param $form_state
* The form state of the (entire) configuration form.
* @param $context
* An associative array with the following elements:
* - formatter: The formatter object.
* - field_definition: The field definition.
* - view_mode: The view mode being configured.
* - form: The (entire) configuration form array.
* @param \Drupal\Core\Field\FormatterInterface $plugin
* The instantiated field formatter plugin.
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
* The field definition.
* @param $view_mode
* The entity view mode.
* @param array $form
* The (entire) configuration form array.
* @param array $form_state
* The form state.
*
* @return array
* Returns the form array to be built.
*
* @see \Drupal\field_ui\DisplayOverView.
*/
function hook_field_formatter_settings_form_alter(&$element, &$form_state, $context) {
// Add a 'mysetting' checkbox to the settings form for 'foo_formatter'
// field formatters.
if ($context['formatter']->getPluginId() == 'foo_formatter') {
$element['mysetting'] = array(
function hook_field_formatter_third_party_settings_form(\Drupal\Core\Field\FormatterInterface $plugin, \Drupal\Core\Field\FieldDefinitionInterface $field_definition, $view_mode, $form, $form_state) {
$element = array();
// Add a 'my_setting' checkbox to the settings form for 'foo_formatter' field
// formatters.
if ($plugin->getPluginId() == 'foo_formatter') {
$element['my_setting'] = array(
'#type' => 'checkbox',
'#title' => t('My setting'),
'#default_value' => $context['formatter']->getSetting('mysetting'),
'#default_value' => $plugin->getThirdPartySetting('my_module', 'my_setting'),
);
}
return $element;
}
/**
* Alters the widget settings form.
* Allow modules to add settings to field widgets provided by other modules.
*
* @param array $element
* Form array.
* @param \Drupal\Core\Field\WidgetInterface $plugin
* The instantiated field widget plugin.
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
* The field definition.
* @param $form_mode
* The entity form mode.
* @param array $form
* The (entire) configuration form array.
* @param array $form_state
* The form state of the (entire) configuration form.
* @param array $context
* An associative array with the following elements:
* - formatter: The formatter object.
* - field_definition: The field definition.
* - form_mode: The form mode being configured.
* - form: The (entire) configuration form array.
* The form state.
*
* @return array
* Returns the form array to be built.
*
* @see \Drupal\field_ui\FormDisplayOverView.
*/
function hook_field_widget_settings_form_alter(&$element, &$form_state, $context) {
// Add a 'mysetting' checkbox to the settings form for 'foo_field' fields.
if ($context['field']['type'] == 'foo_field') {
$element['mysetting'] = array(
function hook_field_widget_third_party_settings_form(\Drupal\Core\Field\WidgetInterface $plugin, \Drupal\Core\Field\FieldDefinitionInterface $field_definition, $form_mode, $form, $form_state) {
$element = array();
// Add a 'my_setting' checkbox to the settings form for 'foo_widget' field
// widgets.
if ($plugin->getPluginId() == 'foo_widget') {
$element['my_setting'] = array(
'#type' => 'checkbox',
'#title' => t('My setting'),
'#default_value' => $context['formatter']->getSetting('mysetting'),
'#default_value' => $plugin->getThirdPartySetting('my_module', 'my_setting'),
);
}
return $element;
}
/**
* Alters the field formatter settings summary.
*
* @param $summary
* The summary.
* @param array $summary
* An array of summary messages.
* @param $context
* An associative array with the following elements:
* - formatter: The formatter object.
......@@ -82,7 +93,7 @@ function hook_field_formatter_settings_summary_alter(&$summary, $context) {
// Append a message to the summary when an instance of foo_formatter has
// mysetting set to TRUE for the current view mode.
if ($context['formatter']->getPluginId() == 'foo_formatter') {
if ($context['formatter']->getSetting('mysetting')) {
if ($context['formatter']->getThirdPartySetting('my_module', 'my_setting')) {
$summary[] = t('My setting enabled.');
}
}
......@@ -92,7 +103,7 @@ function hook_field_formatter_settings_summary_alter(&$summary, $context) {
* Alters the field widget settings summary.
*
* @param array $summary
* The summary.
* An array of summary messages.
* @param array $context
* An associative array with the following elements:
* - widget: The widget object.
......@@ -102,10 +113,10 @@ function hook_field_formatter_settings_summary_alter(&$summary, $context) {
* @see \Drupal\field_ui\FormDisplayOverView.
*/
function hook_field_widget_settings_summary_alter(&$summary, $context) {
// Append a message to the summary when an instance of foo_field has
// Append a message to the summary when an instance of foo_widget has
// mysetting set to TRUE for the current view mode.
if ($context['field']['type'] == 'foo_field') {
if ($context['widget']->getSetting('mysetting')) {
if ($context['widget']->getPluginId() == 'foo_widget') {
if ($context['widget']->getThirdPartySetting('my_module', 'my_setting')) {
$summary[] = t('My setting enabled.');
}
}
......
......@@ -14,6 +14,8 @@
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Field\FieldTypePluginManager;
use Drupal\Core\Field\FormatterInterface;
use Drupal\Core\Field\PluginSettingsInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
......@@ -230,20 +232,26 @@ protected function getFieldLabelOptions() {
/**
* {@inheritdoc}
*/
protected function alterSettingsForm(array &$settings_form, $plugin, FieldDefinitionInterface $field_definition, array $form, array &$form_state) {
$context = array(
'formatter' => $plugin,
'field_definition' => $field_definition,
'view_mode' => $this->mode,
'form' => $form,
);
$this->moduleHandler->alter('field_formatter_settings_form', $settings_form, $form_state, $context);
protected function thirdPartySettingsForm(PluginSettingsInterface $plugin, FieldDefinitionInterface $field_definition, array $form, array &$form_state) {
$settings_form = array();
// Invoke hook_field_formatter_third_party_settings_form(), keying resulting
// subforms by module name.
foreach ($this->moduleHandler->getImplementations('field_formatter_third_party_settings_form') as $module) {
$settings_form[$module] = $this->moduleHandler->invoke($module, 'field_formatter_third_party_settings_form', array(
$plugin,
$field_definition,
$this->mode,
$form,
$form_state,
));
}
return $settings_form;
}
/**
* {@inheritdoc}
*/
protected function alterSettingsSummary(array &$summary, $plugin, FieldDefinitionInterface $field_definition) {
protected function alterSettingsSummary(array &$summary, PluginSettingsInterface $plugin, FieldDefinitionInterface $field_definition) {
$context = array(
'formatter' => $plugin,
'field_definition' => $field_definition,
......