annotate core/lib/Drupal/Core/Field/WidgetPluginManager.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Core\Field;
Chris@0 4
Chris@0 5 use Drupal\Component\Plugin\Factory\DefaultFactory;
Chris@0 6 use Drupal\Core\Cache\CacheBackendInterface;
Chris@0 7 use Drupal\Core\Extension\ModuleHandlerInterface;
Chris@0 8 use Drupal\Core\Plugin\DefaultPluginManager;
Chris@0 9
Chris@0 10 /**
Chris@0 11 * Plugin type manager for field widgets.
Chris@0 12 *
Chris@0 13 * @ingroup field_widget
Chris@0 14 */
Chris@0 15 class WidgetPluginManager extends DefaultPluginManager {
Chris@0 16
Chris@0 17 /**
Chris@0 18 * The field type manager to define field.
Chris@0 19 *
Chris@0 20 * @var \Drupal\Core\Field\FieldTypePluginManagerInterface
Chris@0 21 */
Chris@0 22 protected $fieldTypeManager;
Chris@0 23
Chris@0 24 /**
Chris@0 25 * An array of widget options for each field type.
Chris@0 26 *
Chris@0 27 * @var array
Chris@0 28 */
Chris@0 29 protected $widgetOptions;
Chris@0 30
Chris@0 31 /**
Chris@0 32 * Constructs a WidgetPluginManager object.
Chris@0 33 *
Chris@0 34 * @param \Traversable $namespaces
Chris@0 35 * An object that implements \Traversable which contains the root paths
Chris@0 36 * keyed by the corresponding namespace to look for plugin implementations.
Chris@0 37 * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
Chris@0 38 * Cache backend instance to use.
Chris@0 39 * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
Chris@0 40 * The module handler.
Chris@0 41 * @param \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_manager
Chris@0 42 * The 'field type' plugin manager.
Chris@0 43 */
Chris@0 44 public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, FieldTypePluginManagerInterface $field_type_manager) {
Chris@0 45 parent::__construct('Plugin/Field/FieldWidget', $namespaces, $module_handler, 'Drupal\Core\Field\WidgetInterface', 'Drupal\Core\Field\Annotation\FieldWidget');
Chris@0 46
Chris@0 47 $this->setCacheBackend($cache_backend, 'field_widget_types_plugins');
Chris@0 48 $this->alterInfo('field_widget_info');
Chris@0 49 $this->fieldTypeManager = $field_type_manager;
Chris@0 50 }
Chris@0 51
Chris@0 52 /**
Chris@0 53 * Overrides PluginManagerBase::getInstance().
Chris@0 54 *
Chris@0 55 * @param array $options
Chris@0 56 * An array with the following key/value pairs:
Chris@0 57 * - field_definition: (FieldDefinitionInterface) The field definition.
Chris@0 58 * - form_mode: (string) The form mode.
Chris@0 59 * - prepare: (bool, optional) Whether default values should get merged in
Chris@0 60 * the 'configuration' array. Defaults to TRUE.
Chris@0 61 * - configuration: (array) the configuration for the widget. The
Chris@0 62 * following key value pairs are allowed, and are all optional if
Chris@0 63 * 'prepare' is TRUE:
Chris@0 64 * - type: (string) The widget to use. Defaults to the
Chris@0 65 * 'default_widget' for the field type. The default widget will also be
Chris@0 66 * used if the requested widget is not available.
Chris@0 67 * - settings: (array) Settings specific to the widget. Each setting
Chris@0 68 * defaults to the default value specified in the widget definition.
Chris@0 69 * - third_party_settings: (array) Settings provided by other extensions
Chris@0 70 * through hook_field_formatter_third_party_settings_form().
Chris@0 71 *
Chris@0 72 * @return \Drupal\Core\Field\WidgetInterface|null
Chris@0 73 * A Widget object or NULL when plugin is not found.
Chris@0 74 */
Chris@0 75 public function getInstance(array $options) {
Chris@0 76 // Fill in defaults for missing properties.
Chris@0 77 $options += [
Chris@0 78 'configuration' => [],
Chris@0 79 'prepare' => TRUE,
Chris@0 80 ];
Chris@0 81
Chris@0 82 $configuration = $options['configuration'];
Chris@0 83 $field_definition = $options['field_definition'];
Chris@0 84 $field_type = $field_definition->getType();
Chris@0 85
Chris@0 86 // Fill in default configuration if needed.
Chris@0 87 if ($options['prepare']) {
Chris@0 88 $configuration = $this->prepareConfiguration($field_type, $configuration);
Chris@0 89 }
Chris@0 90
Chris@0 91 $plugin_id = $configuration['type'];
Chris@0 92
Chris@0 93 // Switch back to default widget if either:
Chris@0 94 // - the configuration does not specify a widget class
Chris@0 95 // - the field type is not allowed for the widget
Chris@0 96 // - the widget is not applicable to the field definition.
Chris@0 97 $definition = $this->getDefinition($configuration['type'], FALSE);
Chris@0 98 if (!isset($definition['class']) || !in_array($field_type, $definition['field_types']) || !$definition['class']::isApplicable($field_definition)) {
Chris@0 99 // Grab the default widget for the field type.
Chris@0 100 $field_type_definition = $this->fieldTypeManager->getDefinition($field_type);
Chris@0 101 if (empty($field_type_definition['default_widget'])) {
Chris@0 102 return NULL;
Chris@0 103 }
Chris@0 104 $plugin_id = $field_type_definition['default_widget'];
Chris@0 105 }
Chris@0 106
Chris@0 107 $configuration += [
Chris@0 108 'field_definition' => $field_definition,
Chris@0 109 ];
Chris@0 110 return $this->createInstance($plugin_id, $configuration);
Chris@0 111 }
Chris@0 112
Chris@0 113 /**
Chris@0 114 * {@inheritdoc}
Chris@0 115 */
Chris@0 116 public function createInstance($plugin_id, array $configuration = []) {
Chris@0 117 $plugin_definition = $this->getDefinition($plugin_id);
Chris@0 118 $plugin_class = DefaultFactory::getPluginClass($plugin_id, $plugin_definition);
Chris@0 119
Chris@0 120 // If the plugin provides a factory method, pass the container to it.
Chris@0 121 if (is_subclass_of($plugin_class, 'Drupal\Core\Plugin\ContainerFactoryPluginInterface')) {
Chris@0 122 return $plugin_class::create(\Drupal::getContainer(), $configuration, $plugin_id, $plugin_definition);
Chris@0 123 }
Chris@0 124
Chris@0 125 return new $plugin_class($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings'], $configuration['third_party_settings']);
Chris@0 126 }
Chris@0 127
Chris@0 128 /**
Chris@0 129 * Merges default values for widget configuration.
Chris@0 130 *
Chris@0 131 * @param string $field_type
Chris@0 132 * The field type.
Chris@0 133 * @param array $configuration
Chris@0 134 * An array of widget configuration.
Chris@0 135 *
Chris@0 136 * @return array
Chris@0 137 * The display properties with defaults added.
Chris@0 138 */
Chris@0 139 public function prepareConfiguration($field_type, array $configuration) {
Chris@0 140 // Fill in defaults for missing properties.
Chris@0 141 $configuration += [
Chris@0 142 'settings' => [],
Chris@0 143 'third_party_settings' => [],
Chris@0 144 ];
Chris@0 145 // If no widget is specified, use the default widget.
Chris@0 146 if (!isset($configuration['type'])) {
Chris@0 147 $field_type = $this->fieldTypeManager->getDefinition($field_type);
Chris@0 148 $configuration['type'] = isset($field_type['default_widget']) ? $field_type['default_widget'] : NULL;
Chris@0 149 }
Chris@0 150 // Filter out unknown settings, and fill in defaults for missing settings.
Chris@0 151 $default_settings = $this->getDefaultSettings($configuration['type']);
Chris@0 152 $configuration['settings'] = array_intersect_key($configuration['settings'], $default_settings) + $default_settings;
Chris@0 153
Chris@0 154 return $configuration;
Chris@0 155 }
Chris@0 156
Chris@0 157 /**
Chris@0 158 * Returns an array of widget type options for a field type.
Chris@0 159 *
Chris@0 160 * @param string|null $field_type
Chris@0 161 * (optional) The name of a field type, or NULL to retrieve all widget
Chris@0 162 * options. Defaults to NULL.
Chris@0 163 *
Chris@0 164 * @return array
Chris@0 165 * If no field type is provided, returns a nested array of all widget types,
Chris@0 166 * keyed by field type human name.
Chris@0 167 */
Chris@0 168 public function getOptions($field_type = NULL) {
Chris@0 169 if (!isset($this->widgetOptions)) {
Chris@0 170 $options = [];
Chris@0 171 $field_types = $this->fieldTypeManager->getDefinitions();
Chris@0 172 $widget_types = $this->getDefinitions();
Chris@0 173 uasort($widget_types, ['Drupal\Component\Utility\SortArray', 'sortByWeightElement']);
Chris@0 174 foreach ($widget_types as $name => $widget_type) {
Chris@0 175 foreach ($widget_type['field_types'] as $widget_field_type) {
Chris@0 176 // Check that the field type exists.
Chris@0 177 if (isset($field_types[$widget_field_type])) {
Chris@0 178 $options[$widget_field_type][$name] = $widget_type['label'];
Chris@0 179 }
Chris@0 180 }
Chris@0 181 }
Chris@0 182 $this->widgetOptions = $options;
Chris@0 183 }
Chris@0 184 if (isset($field_type)) {
Chris@0 185 return !empty($this->widgetOptions[$field_type]) ? $this->widgetOptions[$field_type] : [];
Chris@0 186 }
Chris@0 187
Chris@0 188 return $this->widgetOptions;
Chris@0 189 }
Chris@0 190
Chris@0 191 /**
Chris@0 192 * Returns the default settings of a field widget.
Chris@0 193 *
Chris@0 194 * @param string $type
Chris@0 195 * A field widget type name.
Chris@0 196 *
Chris@0 197 * @return array
Chris@0 198 * The widget type's default settings, as provided by the plugin
Chris@0 199 * definition, or an empty array if type or settings are undefined.
Chris@0 200 */
Chris@0 201 public function getDefaultSettings($type) {
Chris@0 202 $plugin_definition = $this->getDefinition($type, FALSE);
Chris@0 203 if (!empty($plugin_definition['class'])) {
Chris@0 204 $plugin_class = DefaultFactory::getPluginClass($type, $plugin_definition);
Chris@0 205 return $plugin_class::defaultSettings();
Chris@0 206 }
Chris@0 207
Chris@0 208 return [];
Chris@0 209 }
Chris@0 210
Chris@0 211 }