json_table-1.0.6/modules/json_gridstack/src/Plugin/Field/FieldWidget/JsonGridStackBlockWidget.php
modules/json_gridstack/src/Plugin/Field/FieldWidget/JsonGridStackBlockWidget.php
<?php
namespace Drupal\json_gridstack\Plugin\Field\FieldWidget;
use Drupal\Core\Block\BlockManagerInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\Context\LazyContextRepository;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines the json gridstack block field widget.
*
* @FieldWidget(
* id = "json_gridstack_block",
* label = @Translation("GridStack blocks"),
* field_types = {"json"},
* )
*/
class JsonGridStackBlockWidget extends WidgetBase implements ContainerFactoryPluginInterface {
/**
* Constructs the plugin instance.
*/
public function __construct(
$plugin_id,
$plugin_definition,
FieldDefinitionInterface $field_definition,
array $settings,
array $third_party_settings,
protected ConfigFactoryInterface $configFactory,
protected EntityTypeManagerInterface $entityTypeManager,
protected BlockManagerInterface $blockManager,
protected LazyContextRepository $contextRepository,
) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new self(
$plugin_id,
$plugin_definition,
$configuration['field_definition'],
$configuration['settings'],
$configuration['third_party_settings'],
$container->get('config.factory'),
$container->get('entity_type.manager'),
$container->get('plugin.manager.block'),
$container->get('context.repository'),
);
}
/**
* {@inheritdoc}
*/
public static function defaultSettings(): array {
$setting = ['blocks' => [], 'attach_library' => ''];
return $setting + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state): array {
$blocks = $this->listBlocks();
$valuesBlock = is_array($this->getSetting('blocks')) ? array_filter($this->getSetting('blocks')) : NULL;
$element['blocks'] = [
'#title' => $this->t('Available blocks'),
'#type' => 'checkboxes',
'#multiple' => TRUE,
'#options' => $blocks,
'#default_value' => !empty($valuesBlock) ? $valuesBlock : [],
'#element_validate' => [[get_class($this), 'fieldOverridesValidate']],
];
$description = '<ul>';
$description .= '<li>' . $this->t('Add library name in textfield , for exmaple add <b>abc/xyz</b> where <b>abc</b> is module or theme name and <b>xyz</b> is library name.') . '</li>';
$description .= '<li>' . $this->t('<b>To add multiple libraries</b>, separate them with a <b>comma(,) separated.</b>') . '</li>';
$description .= '<li>' . $this->t('For more info please read README.md file.') . '</li>';
$description .= '</ul>';
$element['attach_library'] = [
'#type' => 'textfield',
'#title' => $this->t('Attach libraries'),
'#description' => $description,
'#default_value' => $this->getSetting('attach_library'),
];
return $element;
}
/**
* Form element validation handler: Removes empty field overrides.
*
* @param array $element
* The field overrides form element.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state of the entire form.
*/
public static function fieldOverridesValidate(array $element, FormStateInterface $form_state) {
$overrides = $form_state->getValue($element['#parents']);
if (!empty($overrides)) {
$overrides = array_filter($overrides, function ($data) {
return !empty($data);
});
$form_state->setValue($element['#parents'], $overrides);
}
}
/**
* Shows a list of blocks that can be added to a theme's layout.
*
* @inheritDoc
*/
public function listBlocks() {
$definitions = $this->getDefinitions();
$blocks = [];
foreach ($definitions as $plugin_id => $plugin_definition) {
$category = $plugin_definition['category'] ?? NULL;
if ($category && is_object($category)) {
$category = $category->getUntranslatedString();
}
if (str_contains(strtolower($category), 'form')) {
continue;
}
$blocks[$plugin_id] = $plugin_definition['admin_label'] . ' - ' . $plugin_definition['category'];
}
asort($blocks);
return $blocks;
}
/**
* Get blocks definition.
*
* @inheritDoc
*/
public function getDefinitions() {
// Only add blocks which work without any available context.
$definitions = $this->blockManager->getFilteredDefinitions('block_ui', $this->contextRepository->getAvailableContexts());
// Order by category, and then by admin label.
$definitions = $this->blockManager->getSortedDefinitions($definitions);
// Filter out definitions that are not intended to be placed by the UI.
return array_filter($definitions, function (array $definition) {
return empty($definition['_block_ui_hidden']);
});
}
/**
* {@inheritdoc}
*/
public function settingsSummary(): array {
if (!empty($this->getSetting('attach_library'))) {
return [
$this->t('Attach libraries: @attach_library', ['@attach_library' => $this->getSetting('attach_library')]),
];
}
return [];
}
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state): array {
$blocks = $this->listBlocks();
$blockSelected = $this->getSetting('blocks');
if (!empty($blockSelected)) {
foreach ($blockSelected as $bid => &$block) {
$block = $blocks[$bid];
}
}
$element['value'] = $element + [
'#type' => 'textarea',
'#default_value' => $items[$delta]->value ?? NULL,
'#attributes' => ['class' => ['js-hide']],
];
$content = [
'#type' => 'container',
'#attributes' => [
'class' => ['grid-stack', 'vh-100'],
'id' => $items->getName() . '-' . $delta,
],
];
if (!empty($items[$delta]->value)) {
$blockValue = json_decode($items[$delta]->value, TRUE);
foreach ($blockValue as $blockStack) {
$plugin_block = $this->blockManager->createInstance($blockStack['id'], []);
$render = $plugin_block->build();
if (is_array($render) && !empty($render['#type'])) {
foreach ($render as &$el) {
if (is_array($el) && isset($el["#type"]) && $el["#type"] == 'form') {
$el["#type"] = 'container';
}
}
}
$content[] = [
'#theme' => 'json_gridstack_block',
'#id' => $blockStack['id'] ?? '',
'#delta' => $delta,
'#collapse' => FALSE,
'#title' => $blocks[$blockStack['id']] ?? $this->t('Missing block'),
'#content' => $render,
'#weight' => 0,
'#h' => $blockStack['h'] ?? 0,
'#x' => $blockStack['x'] ?? 0,
'#y' => $blockStack['y'] ?? 0,
'#w' => $blockStack['w'] ?? 0,
];
if (isset($blockSelected[$blockStack['id']])) {
unset($blockSelected[$blockStack['id']]);
}
}
}
$element['gridstack'] = [
'#theme' => 'json_gridstack',
'#blocks' => !empty($blockSelected) ? $blockSelected : $blocks,
'#content' => $content,
];
$element['#attached'] = [
'library' => ['json_gridstack/json_gridstack'],
'drupalSettings' => [
'json_gridstack' => [
'blockContent' => Url::fromRoute('json_gridstack.block')->toString(),
$delta => $this->getSetting('mode'),
],
],
];
if (!empty($this->getSetting('attach_library'))) {
$attaches = explode(',', $this->getSetting('attach_library'));
foreach ($attaches as $attach) {
$element['#attached']['library'] = trim($attach);
}
}
return $element;
}
}
