Skip to content
Snippets Groups Projects
Commit 7d07a8fd authored by Mikael Meulle's avatar Mikael Meulle Committed by Pierre Dureau
Browse files

Issue #3490476 by just_like_good_vibes, pdureau: Fix BlockSource

parent 4c65cb6a
No related branches found
No related tags found
No related merge requests found
......@@ -124,7 +124,7 @@ class ComponentElementAlter implements TrustedCallbackInterface {
* @return bool
* Returns true for empty.
*/
public static function isSlotEmpty(array $slot, int $max_level = 2, int $level = 0): bool {
public static function isSlotEmpty(array $slot, int $max_level = 5, int $level = 0): bool {
if (is_array($slot) && empty($slot)) {
return TRUE;
}
......@@ -160,6 +160,10 @@ class ComponentElementAlter implements TrustedCallbackInterface {
unset($slot[$key]);
}
}
if (isset($slot['#access']) && is_string($slot['#access'])) {
// This fix is for isVisibleElement() to work properly.
$slot['#access'] = (bool) $slot['#access'];
}
if (Element::isEmpty($slot) || Element::isVisibleElement($slot) === FALSE) {
return TRUE;
}
......
......@@ -37,6 +37,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
prop_types: ['slot']
)]
class BlockSource extends SourcePluginBase {
/**
* Block to be rendered.
*
......@@ -88,13 +89,42 @@ class BlockSource extends SourcePluginBase {
return $instance;
}
/**
* Alter the element after the form is built.
*
* @param array $element
* The element.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*
* @return array
* The altered element.
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public static function afterBuildBlockForm(array $element, FormStateInterface $form_state) : array {
$element_settings = $form_state->getValue($element['#parents']);
$plugin_id = $element_settings['plugin_id'];
if (!$plugin_id) {
return $element;
}
$form = $form_state->getCompleteForm();
$subform_state = SubformState::createForSubform($element[$plugin_id], $form, $form_state);
$block = \Drupal::service('plugin.manager.block')->createInstance($plugin_id, []);
if ($block instanceof BlockPluginInterface) {
$block->submitConfigurationForm($element, $subform_state);
$configuration = $block->getConfiguration();
$form_state->setValue(array_merge($element['#parents'], [$plugin_id]), $configuration);
}
return $element;
}
/**
* {@inheritdoc}
*/
public function defaultSettings(): array {
return [
'plugin_id' => NULL,
'settings' => [],
];
}
......@@ -107,17 +137,22 @@ class BlockSource extends SourcePluginBase {
if (!$this->block) {
return [];
}
return $this->block->build();
$build = $this->block->build();
if (!is_array($build)) {
return [];
}
return $build;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state): void {
$block = $this->getBlock($form_state->getValue('plugin_id'));
$plugin_id = $form_state->getValue('plugin_id');
$block = $this->getBlock($plugin_id);
if ($block) {
$subform_state = SubformState::createForSubform($form['settings'], $form, $form_state);
$this->getPluginForm($block)->validateConfigurationForm($form['settings'], $subform_state);
$subform_state = SubformState::createForSubform($form[$plugin_id], $form, $form_state);
$this->getPluginForm($block)->validateConfigurationForm($form[$plugin_id], $subform_state);
}
}
......@@ -155,7 +190,7 @@ class BlockSource extends SourcePluginBase {
'#empty_option' => $this->t('- None -'),
'#required' => FALSE,
];
$form["settings"] = [
$form[$plugin_id] = [
'#type' => 'container',
'#attributes' => ["id" => $wrapper_id],
"#tree" => TRUE,
......@@ -165,12 +200,23 @@ class BlockSource extends SourcePluginBase {
// Create a block entity.
$form['#tree'] = TRUE;
// $form['#process'] = [ '::validateForm'];
$form['settings'] = [];
$subform_state = SubformState::createForSubform($form['settings'], $form, $form_state);
$form['settings'] = $this->getPluginForm($block)->buildConfigurationForm($form['settings'], $subform_state);
$form["settings"]['#tree'] = TRUE;
$form['settings']['#prefix'] = '<div id="' . $wrapper_id . '">' . ($form['settings']['#prefix'] ?? '');
$form['settings']['#suffix'] = ($form['settings']['#suffix'] ?? '') . '</div>';
$form[$plugin_id] = [];
$subform_state = SubformState::createForSubform($form[$plugin_id], $form, $form_state);
$form[$plugin_id] = $this->getPluginForm($block)->buildConfigurationForm($form[$plugin_id], $subform_state);
$form[$plugin_id]['#tree'] = TRUE;
$form[$plugin_id]['#prefix'] = '<div id="' . $wrapper_id . '">' . ($form[$plugin_id]['#prefix'] ?? '');
$form[$plugin_id]['#suffix'] = ($form[$plugin_id]['#suffix'] ?? '') . '</div>';
$hide_elements = [
'label',
'label_display',
'admin_label',
];
foreach ($hide_elements as $hide_element) {
if (isset($form[$plugin_id][$hide_element])) {
$form[$plugin_id][$hide_element]['#access'] = FALSE;
}
}
$form['#after_build'][] = [static::class, 'afterBuildBlockForm'];
}
}
......@@ -203,7 +249,7 @@ class BlockSource extends SourcePluginBase {
if (!$plugin_id) {
return NULL;
}
$block_configuration = $this->getSetting('settings') ?? [];
$block_configuration = $this->getSetting($plugin_id) ?? [];
$contexts = $this->context;
/** @var \Drupal\Core\Block\BlockPluginInterface $plugin */
$plugin = $this->blockManager->createInstance($plugin_id, $block_configuration);
......@@ -251,7 +297,10 @@ class BlockSource extends SourcePluginBase {
$subformKeys = $triggeringElement['#array_parents'];
// Remove the triggering element itself and add the 'block' below key.
array_pop($subformKeys);
$subformKeys[] = 'settings';
$parents = $triggeringElement['#parents'];
array_pop($parents);
$plugin_id = $form_state->getValue($parents)['plugin_id'];
$subformKeys[] = $plugin_id;
// Return the subform:
$subform = NestedArray::getValue($form, $subformKeys);
$form_state->setRebuild();
......@@ -327,10 +376,7 @@ class BlockSource extends SourcePluginBase {
// CacheableMetadata::createFromRenderArray($content)
$cache = $element["#cache"] ?? [];
$element["#cache"] = array_merge($cache, [
"max-age" => 0,
// "tags" => ['config:system.menu.' . $this->menuId],
]);
$element["#cache"] = $cache;
return $element;
}
......
......@@ -9,7 +9,7 @@ block_1:
source_id: 'block'
source:
plugin_id: 'ui_patterns_test_block'
settings:
'ui_patterns_test_block':
display_message: "value_text_X"
entity: {}
output:
......
......@@ -46,9 +46,8 @@ function ui_patterns_plugin_filter_block__ui_patterns_alter(array &$definitions,
// Add a boolean marker '_ui_patterns_compatible' to all remaining definitions
// Other modules can use the same hook to modify this value.
// This allows to add or remove blocks.
$allowed_blocks = [
"id" => ["search_form_block", "system_menu_block"],
"provider" => ["views"],
$forbidden_blocks = [
"provider" => ["layout_builder", "ui_patterns_blocks"],
];
foreach ($definitions as $id => &$definition) {
if (isset($definitions[$id]['_ui_patterns_compatible'])) {
......@@ -58,25 +57,8 @@ function ui_patterns_plugin_filter_block__ui_patterns_alter(array &$definitions,
continue;
}
$compatibilityFlag = TRUE;
if (in_array($definition['provider'], $allowed_blocks["provider"]) ||
in_array($definition["id"], $allowed_blocks["id"])) {
// The block stays accepted.
}
elseif (isset($definition['class'])) {
try {
$class_name = $definition['class'];
$reflector = new \ReflectionClass($class_name);
if ($reflector->hasMethod("blockSubmit") && ($reflector->getMethod("blockSubmit")->getDeclaringClass()->getName() === $class_name)) {
// Blocks having a custom implementation are discarded,
// because some blocks may store in their configuration
// a different structure than the form structure.
// We can't support this properly yet.
$compatibilityFlag = FALSE;
}
}
catch (\ReflectionException $e) {
// The block stays accepted.
}
if (in_array($definition['provider'], $forbidden_blocks["provider"])) {
$compatibilityFlag = FALSE;
}
// Filter out blocks with _block_ui_hidden ?
$definitions[$id]['_ui_patterns_compatible'] = $compatibilityFlag;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment