diff --git a/fieldblock.install b/fieldblock.install index f1da813453eccdc9a6940617447548ff91b647d3..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/fieldblock.install +++ b/fieldblock.install @@ -1,86 +0,0 @@ -<?php - -///** -// * Implements hook_uninstall(). -// */ -//function fieldblock_uninstall() { -// // Delete variables. -// $entities = entity_get_info(); -// // Loop over the entity types. -// foreach ($entities as $entity_type => $entity_info) { -// // Loop over each entity type's bundles. -// foreach ($entity_info['bundles'] as $bundle => $bundle_info) { -// $view_modes = field_view_mode_settings($entity_type, $bundle); -// // Treat the default settings as a real view mode with custom settings. -// $view_modes['default']['custom_settings'] = true; -// // Loop over the bundle's view modes. -// foreach ($view_modes as $view_mode => $view_mode_info) { -// // Delete the variable, if it exists. -// $variable_name = 'fieldblock-'. $entity_type .'-'. $bundle .'-'. $view_mode; -// variable_del($variable_name); -// } -// } -// } -//} -// -///** -// * Legacy helper function to undo drupal core schema alter. -// */ -//function _fieldblock_db_alter_block_delta_length($length) { -// // Alter block table. -// db_drop_unique_key('block', 'tmd'); -// db_change_field('block', 'delta', 'delta', -// array( -// 'type' => 'varchar', -// 'length' => $length, -// 'not null' => TRUE, -// 'default' => '0', -// 'description' => 'Unique ID for block within a module.', -// ), -// array( -// 'unique keys' => array( -// 'tmd' => array('theme', 'module', 'delta'), -// ) -// ) -// ); -// -// // Alter block_role table. -// db_drop_primary_key('block_role'); -// db_change_field('block_role', 'delta', 'delta', -// array( -// 'type' => 'varchar', -// 'length' => $length, -// 'not null' => TRUE, -// 'description' => "The block's unique delta within module, from {block}.delta.", -// ), -// array( -// 'primary key' => array('module', 'delta', 'rid'), -// ) -// ); -// -// // Alter block_node_type table. -// db_drop_primary_key('block_node_type'); -// db_change_field('block_node_type', 'delta', 'delta', -// array( -// 'type' => 'varchar', -// 'length' => $length, -// 'not null' => TRUE, -// 'description' => "The block's unique delta within module, from {block}.delta.", -// ), -// array( -// 'primary key' => array('module', 'delta', 'type'), -// ) -// ); -//} -// -///** -// * Update legacy fieldblock deltas to use md5 identifier. -// * Reset drupal core block schema. -// */ -//function fieldblock_update_7100() { -// $blocks = db_query("SELECT bid, delta FROM {block} WHERE module = 'fieldblock'"); -// foreach ($blocks as $block) { -// db_query("UPDATE {block} SET delta = :new_delta WHERE bid = :bid AND delta = :old_delta AND module = 'fieldblock'", array(':new_delta' => md5($block->delta), ':bid' => $block->bid, ':old_delta' => $block->delta)); -// } -// _fieldblock_db_alter_block_delta_length(32); -//} diff --git a/fieldblock.module b/fieldblock.module index 01a63b10541a35dcc593e60727130fdcbf5c9d21..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/fieldblock.module +++ b/fieldblock.module @@ -1,113 +0,0 @@ -<?php - -/** - * @file - * Allow fields to be rendered in blocks. - */ - -use Drupal\Core\Form\FormStateInterface; -use Drupal\Core\Entity\Entity\EntityViewDisplay; -use Drupal\Core\Entity\Display\EntityViewDisplayInterface; - -/** - * Implements hook_form_alter(). - * - * Adds a column to the "display fields" table-form, with a checkbox for each - * field. - */ -function fieldblock_form_field_ui_display_overview_form_alter(&$form, FormStateInterface &$form_state, $form_id) { - $entity_type = $form['#entity_type']; - $bundle = $form['#bundle']; - $mode = $form['#mode']; - - /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $entity_view_display */ - $entity_view_display = EntityViewDisplay::load($entity_type . '.' . $bundle . '.' . $mode); - - // Add a column header. - $form['fields']['#header'][] = t('Display as block'); - - // Add checkboxes. - $field_names = array_merge($form['#fields'], $form['#extra']); - foreach ($field_names as $field_name) { - $form['fields'][$field_name]['fieldblock'] = array( - '#type' => 'checkbox', - '#default_value' => $entity_view_display->getThirdPartySetting('fieldblock', $field_name) ? true : false, - '#title' => '', - ); - } - - // Add a submit handler. - $form['#submit'][] = 'fieldblock_field_display_submit'; -} - -/** - * Form submit handler for field_ui_display_overview_form. - * Stores which fields are published as blocks as a third_party_settings array - * in the EntityViewDisplay object of the entity type / bundle / view mode. - * - * @param mixed[] $form - * A form API array. - * @param \Drupal\Core\Form\FormStateInterface $form_state - * The state of the submitted form. - */ -function fieldblock_field_display_submit($form, FormStateInterface $form_state) { - $entity_type = $form['#entity_type']; - $bundle = $form['#bundle']; - $mode = $form['#mode']; - - /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $entity_view_display */ - $entity_view_display = EntityViewDisplay::load($entity_type . '.' . $bundle . '.' . $mode); - - $fields = $form_state->getValue('fields'); - foreach ($fields as $field_name => $field) { - if (isset($field['fieldblock']) && $field['fieldblock'] == 1) { - $entity_view_display->setThirdPartySetting('fieldblock', $field_name, $form['fields'][$field_name]['human_name']['#markup']); - } - else if ($entity_view_display->getThirdPartySetting('fieldblock', $field_name)) { - $entity_view_display->unsetThirdPartySetting('fieldblock', $field_name); - } - } - $entity_view_display->save(); - - // Invalidate the block cache to update fielblock derivatives. - if (\Drupal::moduleHandler()->moduleExists('block')) { - \Drupal::service('plugin.manager.block')->clearCachedDefinitions(); - } -} - -/** - * Implements hook_entity_view_alter(). - * - * Takes fields out of the current entity and caches them in a post render cache - * context. The #post_render_cache callback makes this data available to the - * fieldblock when it is built, We also hide the field from the render array. - * - * @param array &$build - * A renderable array representing the entity content. - * @param \Drupal\Core\Entity\EntityInterface $entity - * The entity object being rendered. Not used in this implementation. - * @param \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display - * The entity view display holding the display options configured for the - * entity components. - * - * @see \Drupal\fieldblock\Plugin\Block\FieldBlock::fieldBlockPostRenderCache - * @see https://www.drupal.org/node/2151609 - */ -function fieldblock_entity_view_alter(array &$build, $entity, EntityViewDisplayInterface $display) { - $fieldblock_settings = $display->getThirdPartySettings('fieldblock'); - $display_id = $display->get('id'); - - foreach ($fieldblock_settings as $field_name => $field_label) { - $fieldblock_id = $display_id . ':' . $field_name; - - if (count(\Drupal\Core\Render\Element::children($build[$field_name]))) { - // This is where we take out the field and cache it in a post render - // cache context. - $build['#post_render_cache']['Drupal\fieldblock\Plugin\Block\FieldBlock::fieldBlockPostRenderCache'][] = array( - 'build' => $build[$field_name], - 'fieldblock_id' => $fieldblock_id, - ); - hide($build[$field_name]); - } - } -} diff --git a/schema/fieldblock.schema.yml b/schema/fieldblock.schema.yml new file mode 100644 index 0000000000000000000000000000000000000000..0358d19d1ad72800f36b0459dcfe2f4e768a2682 --- /dev/null +++ b/schema/fieldblock.schema.yml @@ -0,0 +1,18 @@ +# Schema for the configuration files of the Field as Block module. + +block.settings.fieldblock:*: + type: block_settings + label: 'Field as Block' + mapping: + label_from_field: + type: boolean + lable: 'Use field label as block title' + field_name: + type: string + label: 'Field name' + formatter_id: + type: string + label: 'Format type machine name' + formatter_settings: + type: field.formatter.settings.[%parent.formatter_id] + label: 'Settings' diff --git a/src/Plugin/Block/FieldBlock.php b/src/Plugin/Block/FieldBlock.php index fd769bbf69d20bc47672e83fd77e2a0b03f88158..477877b7ccc3289111a2f5bc8ebe01c83b970b95 100644 --- a/src/Plugin/Block/FieldBlock.php +++ b/src/Plugin/Block/FieldBlock.php @@ -6,82 +6,358 @@ */ namespace Drupal\fieldblock\Plugin\Block; + +use Drupal\Core\Access\AccessResult; use Drupal\Core\Block\BlockBase; +use Drupal\Core\Entity\ContentEntityInterface; +use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityManagerInterface; +use Drupal\Core\Field\BaseFieldDefinition; +use Drupal\Core\Field\FieldDefinitionInterface; +use Drupal\Core\Field\FormatterInterface; +use Drupal\Core\Field\FormatterPluginManager; +use Drupal\Core\Form\FormHelper; +use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\Routing\RouteMatchInterface; +use Drupal\Core\Session\AccountInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Provides a fieldblock. * * @Block( * id = "fieldblock", - * admin_label = @Translation("Fieldblock"), - * deriver = "Drupal\fieldblock\Plugin\Derivative\FieldBlock" + * admin_label = @Translation("Field as Block"), + * deriver = "Drupal\fieldblock\Plugin\Derivative\FieldBlockDeriver" * ) */ -class FieldBlock extends BlockBase { +class FieldBlock extends BlockBase implements ContainerFactoryPluginInterface { + + /** + * The entity manager. + * + * @var \Drupal\Core\Entity\EntityManagerInterface + */ + protected $entityManager; + + /** + * The field formatter plugin manager. + * + * @var \Drupal\Core\Field\FormatterPluginManager + */ + protected $formatterPluginManager; + + /** + * The current route match. + * + * @var \Drupal\Core\Routing\RouteMatchInterface + */ + protected $routeMatch; /** * {@inheritdoc} + * + * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager + * The entity manager. + * @param \Drupal\Core\Field\FormatterPluginManager $formatter_plugin_manager + * The field formatter plugin manager. + * @param \Drupal\Core\Routing\RouteMatchInterface $route_match + * The current route match. */ - public function build() { - $block_id = $this->getDerivativeId(); - $block = $this::getFieldBlock($block_id); - return $block; + public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager, FormatterPluginManager $formatter_plugin_manager, RouteMatchInterface $route_match) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + $this->entityManager = $entity_manager; + $this->formatterPluginManager = $formatter_plugin_manager; + $this->routeMatch = $route_match; } /** - * @var array[] - * Static storage for fields that are grabbed from the entity's render - * array, to be retrieved when fieldblocks are built. + * {@inheritdoc} */ - protected static $fieldBlocks; + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static($configuration, + $plugin_id, + $plugin_definition, + $container->get('entity.manager'), + $container->get('plugin.manager.field.formatter'), + $container->get('current_route_match')); + } /** - * @param string $fieldblock_id - * The identifier of the fieldblock. - * @return mixed[]|false - * The render array of the field that is published as block or false if the - * field is not available. + * {@inheritdoc} */ - public static function getFieldBlock($fieldblock_id) { - if (isset(self::$fieldBlocks[$fieldblock_id])) { - return self::$fieldBlocks[$fieldblock_id]; + public function defaultConfiguration() { + return [ + 'label_from_field' => TRUE, + 'field_name' => '', + 'formatter_id' => '', + 'formatter_settings' => [] + ]; + } + + protected function getFieldOptions() { + $field_definitions = $this->entityManager->getFieldStorageDefinitions($this->getDerivativeId()); + $options = []; + foreach ($field_definitions as $definition) { + $options[$definition->getName()] = $definition->getLabel(); + } + return $options; + } + + protected function getFormatterOptions(FieldDefinitionInterface $field_definition) { + $options = $this->formatterPluginManager->getOptions($field_definition->getType()); + foreach ($options as $id => $label) { + $definition = $this->formatterPluginManager->getDefinition($id, FALSE); + $formatter_plugin_class = isset($definition['class']) ? $definition['class'] : NULL; + $applicable = $formatter_plugin_class instanceof FormatterInterface && $formatter_plugin_class::isApplicable($field_definition); + if ($applicable) { + unset($options[$id]); + } } - else { - return FALSE; + return $options; + } + + /** + * Gets the field definition. + * + * A FieldBlock works on an entity type across bundles, and thus only has access to + * field storage definitions. In order to be able to use formatters, we create a + * generic field definition out of that storage definition. + * + * @param string $field_name + * + * @see BaseFieldDefinition::createFromFieldStorageDefinition() + * @see \Drupal\views\Plugin\views\field\Field::getFieldDefinition() + * + * @return \Drupal\Core\Field\FieldDefinitionInterface + * The field definition used by this block. + */ + protected function getFieldDefinition($field_name) { + $field_storage_config = $this->getFieldStorageDefinition($field_name); + return BaseFieldDefinition::createFromFieldStorageDefinition($field_storage_config); + } + + /** + * Gets the field storage definition. + * + * @param string $field_name + * + * @return \Drupal\field\FieldStorageConfigInterface + * The field storage definition used by this block. + */ + protected function getFieldStorageDefinition($field_name) { + $field_storage_definitions = $this->entityManager->getFieldStorageDefinitions($this->getDerivativeId()); + return $field_storage_definitions[$field_name]; + } + + /** + * {@inheritdoc} + */ + public function blockForm($form, FormStateInterface $form_state) { + $form['label_from_field'] = [ + '#title' => $this->t('Use field label as block title'), + '#type' => 'checkbox', + '#default_value' => $this->configuration['label_from_field'], + ]; + + $form['field_name'] = [ + '#title' => $this->t('Field'), + '#type' => 'select', + '#options' => $this->getFieldOptions(), + '#default_value' => $this->configuration['field_name'], + '#required' => TRUE, + '#ajax' => [ + 'callback' => [$this, 'blockFormChangeFieldOrFormatterAjax'], + 'wrapper' => 'edit-block-formatter-wrapper', + ], + ]; + + $form['formatter'] = [ + '#type' => 'container', + '#id' => 'edit-block-formatter-wrapper' + ]; + + $field_name = $form_state->getValue(['settings', 'field_name'], $this->configuration['field_name']); + $field_definition = NULL; + $formatter_id = $form_state->getValue(['settings', 'formatter', 'id'], $this->configuration['formatter_id']); + + if ($field_name) { + $field_definition = $this->getFieldDefinition($field_name); + $formatter_options = $this->getFormatterOptions($field_definition); + if (empty($formatter_options)) { + $formatter_id = ''; + } + else { + if (empty($formatter_id)) { + $formatter_id = reset($formatter_options); + } + $form['formatter']['id'] = [ + '#title' => $this->t('Formatter'), + '#type' => 'select', + '#options' => $formatter_options, + '#default_value' => $this->configuration['formatter_id'], + '#required' => TRUE, + '#ajax' => [ + 'callback' => [$this, 'blockFormChangeFieldOrFormatterAjax'], + 'wrapper' => 'edit-block-formatter-wrapper', + ], + ]; + } + } + + $form['formatter']['change'] = [ + '#type' => 'submit', + '#name' => 'fieldblock_change_field', + '#value' => $this->t('Change field'), + '#attributes' => ['class' => ['js-hide']], + '#limit_validation_errors' => [['settings']], + '#submit' => [[get_class($this), 'blockFormChangeFieldOrFormatter']], + ]; + + if ($formatter_id) { + $formatter_settings = $this->configuration['formatter_settings'] + $this->formatterPluginManager->getDefaultSettings($formatter_id); + $formatter_options = [ + 'field_definition' => $field_definition, + 'view_mode' => '_custom', + 'configuration' => [ + 'type' => $formatter_id, + 'settings' => $formatter_settings, + 'label' => '', + 'weight' => 0, + ] + ]; + + if ($formatter_plugin = $this->formatterPluginManager->getInstance($formatter_options)) { + $formatter_settings_form = $formatter_plugin->settingsForm($form, $form_state); + // Convert field UI selector states to work in the block configuration form. + FormHelper::rewriteStatesSelector($formatter_settings_form, + "fields[{$field_name}][settings_edit_form]", + 'settings[formatter][settings]'); + } + if (!empty($formatter_settings_form)) { + $form['formatter']['settings'] = $formatter_settings_form; + $form['formatter']['settings']['#type'] = 'fieldset'; + $form['formatter']['settings']['#title'] = $this->t('Formatter settings'); + } } + + return $form; } /** - * @param string $fieldblock_id - * The identifier of the fieldblock. - * @param mixed[] $render_array - * The render array of the field that will be published as block. + * Element submit handler for non-JS field/formatter changes. + * + * @param array $form + * @param \Drupal\Core\Form\FormStateInterface $form_state */ - public static function setFieldBlock($fieldblock_id, array $render_array) { - self::$fieldBlocks[$fieldblock_id] = $render_array; + public static function blockFormChangeFieldOrFormatter(array $form, FormStateInterface $form_state) { + $form_state->setRebuild(); } /** - * #post_render_cache callback, temporarily stores a field's render array in a - * static variable and returns the original element as post render cache - * callbacks are supposed to do. + * Ajax callback on changing field_name or formatter_id form element. * - * Note that this is an atypical way to use the post render cache mechanism. - * Post render cache is meant to allow modules to dynamically alter pieces of - * cached content. Here we use it as some kind of context-aware cache, because - * the cached field will only be retrieved and displayed as a block when the - * entity is viewed. + * @param $form * - * @param mixed[] $element - * The render array being rendered. - * @param mixed[] $context - * Array containing the fieldblock ID and the field's render array. - * @return mixed[] - * The render array being rendered. + * @return array + * The part of the form that has changed. + */ + public function blockFormChangeFieldOrFormatterAjax($form) { + return $form['settings']['formatter']; + } + + /** + * {@inheritdoc} + */ + public function blockValidate($form, FormStateInterface $form_state) { + parent::blockValidate($form, $form_state); + } + + /** + * {@inheritdoc} */ - public static function fieldBlockPostRenderCache(array $element, array $context) { - self::setFieldBlock($context['fieldblock_id'], $context['build']); - return $element; + public function blockSubmit($form, FormStateInterface $form_state) { + $this->configuration['label_from_field'] = $form_state->getValue('label_from_field'); + $this->configuration['field_name'] = $form_state->getValue('field_name'); + $this->configuration['formatter_id'] = $form_state->getValue(['formatter', 'id'], ''); + $this->configuration['formatter_settings'] = $form_state->getValue(['formatter', 'settings'], []); } + /** + * {@inheritdoc} + * + * @see \Drupal\views\Plugin\views\field\Field::calculateDependencies() + */ + public function calculateDependencies() { + $dependencies = parent::calculateDependencies(); + + // Add the module providing the configured field storage as a dependency. + if (($field_storage_definition = $this->getFieldStorageDefinition($this->configuration['field_name'])) && $field_storage_definition instanceof EntityInterface) { + $dependencies['config'][] = $field_storage_definition->getConfigDependencyName(); + } + // Add the module providing the formatter. + if (!empty($this->configuration['formatter_id'])) { + $dependencies['module'][] = $this->formatterPluginManager->getDefinition($this->configuration['formatter_id'])['provider']; + } + + return $dependencies; + } + + /** + * {@inheritdoc} + */ + protected function blockAccess(AccountInterface $account) { + $entity_type = $this->getDerivativeId(); + $entity = $this->routeMatch->getParameter($entity_type); + + if ($entity instanceof ContentEntityInterface && $entity->getEntityTypeId() === $entity_type && $entity->hasField($this->configuration['field_name'])) { + $field = $entity->get($this->configuration['field_name']); + return AccessResult::allowedIf(!$field->isEmpty() && $field->access('view', $account)); + } + return AccessResult::forbidden(); + } + + /** + * {@inheritdoc} + */ + public function build() { + $build = []; + $entity_type = $this->getDerivativeId(); + $entity = $this->routeMatch->getParameter($entity_type); + + if ($entity instanceof ContentEntityInterface) { + $build['field'] = $entity->get($this->configuration['field_name'])->view([ + 'label' => 'hidden', + 'type' => $this->configuration['formatter_id'], + 'settings' => $this->configuration['formatter_settings'] + ]); + if ($this->configuration['label_from_field'] && !empty($build['field']['#title'])) { + $build['#title'] = $build['field']['#title']; + } + } + + return $build; + } + + /** + * {@inheritdoc} + */ + public function getCacheTags() { + $entity_type = $this->getDerivativeId(); + $entity = $this->routeMatch->getParameter($entity_type); + if ($entity instanceof ContentEntityInterface) { + return $entity->getCacheTags(); + } + return parent::getCacheTags(); + } + + /** + * {@inheritdoc} + */ + public function getCacheContexts() { + // This block must be cached per URL: every entity has its own canonical url + // and its own fields. + return ['url']; + } } diff --git a/src/Plugin/Derivative/FieldBlock.php b/src/Plugin/Derivative/FieldBlock.php index 0d5a670a58a06252d057554e269fbb9429e5511d..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/src/Plugin/Derivative/FieldBlock.php +++ b/src/Plugin/Derivative/FieldBlock.php @@ -1,105 +0,0 @@ -<?php - -/** - * @file - * Contains \Drupal\fieldblock\Plugin\Derivative\FieldBlock. - */ - -namespace Drupal\fieldblock\Plugin\Derivative; - -use Drupal\Component\Plugin\Derivative\DeriverBase; -use Drupal\Core\Entity\EntityManagerInterface; -use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface; -use Drupal\Core\StringTranslation\StringTranslationTrait; -use Drupal\Core\StringTranslation\TranslationInterface; -use Symfony\Component\DependencyInjection\ContainerInterface; - -/** - * Provides block plugin definitions for fieldblock blocks. - * - * @see \Drupal\fieldblock\Plugin\Block\FieldBlock - */ -class FieldBlock extends DeriverBase implements ContainerDeriverInterface { - - use StringTranslationTrait; - - /** - * The entity view display storage. - * - * @var \Drupal\Core\Entity\EntityStorageInterface - */ - protected $entityViewDisplayStorage; - - /** - * Constructs a FieldBlock deriver object. - * - * @param \Drupal\Core\Entity\Entity\EntityViewDisplay $entity_view_display - * The entity view display storage. - * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation - * The string translation. - */ - public function __construct($entity_view_display, TranslationInterface $string_translation) { - $this->entityViewDisplayStorage = $entity_view_display; - $this->stringTranslation = $string_translation; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container, $base_plugin_id) { - /** @var EntityManagerInterface $entity_manager */ - $entity_manager = $container->get('entity.manager'); - return new static( - $entity_manager->getStorage('entity_view_display'), - $container->get('string_translation') - ); - } - - /** - * {@inheritdoc} - */ - public function getDerivativeDefinitions($base_plugin_definition) { - $blocks = $this->fieldBlockGetBlockList(); - - foreach ($blocks as $fieldblock_id => $description) { - $this->derivatives[$fieldblock_id] = $base_plugin_definition; - $this->derivatives[$fieldblock_id]['admin_label'] = $description; - } - - return $this->derivatives; - } - - /** - * Builds a list of fields that have been made available as a block. - * - * @return string[] - * An array of fieldblocks in the form of fieldblock_id => admin label. - */ - protected function fieldBlockGetBlockList() { - $fieldblocks = array(); - - // Get all EntityViewDisplay config entities and iterate over them. - $entity_view_displays = $this->entityViewDisplayStorage->loadMultiple(); - - /** @var \Drupal\Core\Entity\EntityDisplayModeInterface $entity_view_display */ - foreach ($entity_view_displays as $display_id => $entity_view_display) { - $view_display_fieldblocks = $entity_view_display->getThirdPartySettings('fieldblock'); - $entity_type = $entity_view_display->get('targetEntityType'); - $bundle = $entity_view_display->get('bundle'); - $mode = $entity_view_display->get('mode'); - - foreach ($view_display_fieldblocks as $field_name => $field_label) { - $fieldblock_id = $display_id . ':' . $field_name; - $fieldblocks[$fieldblock_id] = $this->t('@field field (from @type: @bundle: @mode)', array( - '@field' => $field_label, - '@type' => $entity_type, - '@bundle' => $bundle, - '@mode' => $mode, - )); - } - } - - return $fieldblocks; - } - -} diff --git a/src/Plugin/Derivative/FieldBlockDeriver.php b/src/Plugin/Derivative/FieldBlockDeriver.php new file mode 100644 index 0000000000000000000000000000000000000000..3c814b0fa95060014ae5a2ec69a25b8ec15bc37b --- /dev/null +++ b/src/Plugin/Derivative/FieldBlockDeriver.php @@ -0,0 +1,69 @@ +<?php + +/** + * @file + * Contains \Drupal\fieldblock\Plugin\Derivative\FieldBlockDeriver. + */ + +namespace Drupal\fieldblock\Plugin\Derivative; + +use Drupal\Component\Plugin\Derivative\DeriverBase; +use Drupal\Core\Entity\ContentEntityTypeInterface; +use Drupal\Core\Entity\EntityManagerInterface; +use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface; +use Drupal\Core\StringTranslation\StringTranslationTrait; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Provides block plugin definitions for fieldblock blocks. + * + * @see \Drupal\fieldblock\Plugin\Block\FieldBlock + */ +class FieldBlockDeriver extends DeriverBase implements ContainerDeriverInterface { + + use StringTranslationTrait; + + /** + * The entity manager. + * + * @var \Drupal\Core\Entity\EntityManagerInterface + */ + protected $entityManager; + + /** + * Constructs a FieldBlockDeriver object. + * + * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager + * The entity manager. + */ + public function __construct(EntityManagerInterface $entity_manager) { + $this->entityManager = $entity_manager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, $base_plugin_id) { + return new static( + $container->get('entity.manager') + ); + } + + /** + * {@inheritdoc} + */ + public function getDerivativeDefinitions($base_plugin_definition) { + $definitions = $this->entityManager->getDefinitions(); + + foreach ($definitions as $entity_type_id => $definition) { + if ($definition instanceof ContentEntityTypeInterface) { + $this->derivatives[$entity_type_id] = $base_plugin_definition; + $this->derivatives[$entity_type_id]['admin_label'] = $this->t('@type field', [ + '@type' => $definition->getLabel(), + ]); + } + } + + return $this->derivatives; + } +}