View source
<?php
namespace Drupal\gridstack\Plugin\gridstack\stylizer;
use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Url;
use Drupal\Core\Render\Element;
use Drupal\gridstack\GridStackDefault;
use Drupal\gridstack\Entity\GridStack;
use Drupal\gridstack\Entity\GridStackVariant;
class Builder extends Style {
private $variantOptions;
public function attach(array &$load, array $attach = []) {
parent::attach($load, $attach);
if (!empty($attach['_ipe'])) {
$load['library'][] = 'gridstack/admin_modal';
$load['library'][] = 'gridstack/admin_layout';
if (!empty($attach['library'])) {
$library = $attach['library'];
if (strpos($library, ',') !== FALSE) {
$items = array_map('trim', explode(',', $library));
foreach ($items as $item) {
$load['library'][] = $item;
}
}
else {
$load['library'][] = $library;
}
}
}
}
public function adminAttributes(array &$box, array &$content_attributes, array $settings, array $regions = []) {
$rid = isset($settings['rid']) ? $settings['rid'] : -1;
$region = isset($regions[$rid]) ? $regions[$rid] : [];
if (!empty($region['#attributes']) && is_array($region['#attributes'])) {
$this
->lb($box, $content_attributes, $settings, $region);
}
if (!empty($settings['_panels']) && !empty($region['#prefix'])) {
$this
->panels($box, $settings, $region);
}
}
public function rootAttributes(array &$attributes, array $styles) {
if ($rules = $this
->parseStyles($styles, FALSE)) {
$attributes['data-gs-inline-styles'] = Json::encode(reset($rules));
}
}
public function inlineAttributes(array &$attributes, array $data) {
$rules = $data['rules'];
$selector = $data['selector'];
if (!empty($rules[$selector])) {
$this
->inlineStyle($attributes, $rules[$selector]);
}
}
public function regions(array $element) {
$regions = [];
foreach (Element::children($element) as $child) {
if ($child == 'items') {
continue;
}
$regions[$child] = $element[$child];
}
return $regions;
}
private function lb(array &$box, array &$content_attributes, array $settings, array $region = []) {
$rid = isset($settings['rid']) ? $settings['rid'] : -1;
$content_attributes = NestedArray::mergeDeep($content_attributes, $region['#attributes']);
if (isset($region['layout_builder_add_block'])) {
$link = $region['layout_builder_add_block'];
$link['#attributes']['class'][] = 'gridstack__action';
$link['#attributes']['data-gs-region'] = $rid;
$link['#weight'] = 100;
if (isset($link['link'], $link['link']['#url'])) {
$label = 'data-layout-content-preview-placeholder-label';
foreach (Element::children($box) as $uuid) {
$params = $link['link']['#url']
->getRouteParameters() + [
'uuid' => $uuid,
];
$fallback = isset($box[$uuid]['#attributes'][$label]) ? $box[$uuid]['#attributes'][$label] : '';
$box[$uuid]['#attributes']['class'][] = 'js-layout-builder-block layout-builder-block';
$box[$uuid]['#attributes']['data-layout-block-uuid'] = $uuid;
$box[$uuid]['#attributes']['data-layout-builder-highlight-id'] = $uuid;
if (!empty($settings['_lbux'])) {
assert(isset($box[$uuid]['content']));
$box[$uuid]['content'] = [
'actions' => $this
->lbux($params, $fallback),
'content' => $box[$uuid]['content'],
];
}
else {
$box[$uuid]['#contextual_links'] = $this
->contextualLinks($params);
}
}
}
if (isset($region['region_label'])) {
$box['region_label'] = $region['region_label'];
}
$box['add_block'] = $link;
}
}
private function panels(array &$box, array $settings, array $region = []) {
$box['#prefix'] = $region['#prefix'];
$box['#suffix'] = $region['#suffix'];
foreach (Element::children($box) as $bid) {
if (isset($region[$bid]['#attributes']['data-block-id'])) {
$box[$bid]['#attributes']['data-block-id'] = $region[$bid]['#attributes']['data-block-id'];
}
}
}
private function contextualLinks(array $params) {
return [
'layout_builder_block' => [
'route_parameters' => $params,
'metadata' => [
'operations' => 'move:update:remove',
],
],
];
}
private function lbux(array $params, $fallback) {
$links = [
'#type' => 'container',
'#attributes' => [
'class' => [
'layout-builder__actions',
'layout-builder__actions__block',
'layout-builder__actions--block',
],
'tabindex' => 0,
],
'label' => [
'#type' => 'html_tag',
'#tag' => 'span',
'#attributes' => [
'class' => [
'layout-builder__block-label',
],
],
'content' => [
'#markup' => $fallback,
],
],
'move' => [
'#url' => Url::fromRoute('layout_builder.move_block_form', $params),
],
'configure' => [
'#url' => Url::fromRoute('layout_builder.update_block', $params),
],
'remove' => [
'#url' => Url::fromRoute('layout_builder.remove_block', $params),
],
];
foreach ([
'move',
'configure',
'remove',
] as $key) {
$title = $this
->t('@title @block', [
'@title' => ucwords($key),
'@block' => $fallback,
]);
$links[$key]['#type'] = 'link';
$links[$key]['#title'] = [
'#markup' => '<span class="visually-hidden">' . $title . '</span>',
'#allowed_tags' => [
'span',
],
];
$links[$key]['#attributes'] = [
'class' => [
'use-ajax',
'layout-builder__link',
'layout-builder__link--' . $key,
],
'data-dialog-type' => 'dialog',
'data-dialog-renderer' => 'off_canvas',
];
}
return $links;
}
public function getVariantLinks(array $settings, $optionset, $reload = FALSE) {
if (empty($settings['gid']) || empty($settings['optionset'])) {
return [];
}
$links = [];
$name = $settings['optionset'];
$vid = isset($settings['vid']) ? $settings['vid'] : '';
$dup = isset($settings['dup']) ? $settings['dup'] : '';
$gid = GridStackDefault::gid($settings['gid']);
$params = [
'gridstack' => $name,
'gid' => $gid,
];
$options = [];
$variant = $vid ? GridStackVariant::load($vid) : NULL;
$pub = empty($settings['pub']) ? NULL : $settings['pub'];
$params['gridstack_variant'] = $vid;
if (!empty($settings['_variant']) && $vid) {
$pub = $vid;
}
if ($dup) {
$params['dup'] = $dup;
}
if ($pub) {
$params['pub'] = $pub;
}
foreach ([
'add',
'cancel',
'delete',
'duplicate',
'edit',
'select',
] as $key) {
$title = $key == 'select' ? 'variants' : $key . ' variant';
$title = $key == 'cancel' ? $key : $title;
$links[$key]['#type'] = 'link';
$links[$key]['#title'] = $this
->t('@title', [
'@title' => ucwords($title),
]);
$links[$key]['#attributes']['class'] = [
'use-ajax',
'btn',
'btn-primary',
'btn--editor',
'btn--editor-' . $key,
];
}
if (empty($variant)) {
$links['cancel'] = [];
$links['delete'] = [];
$links['duplicate'] = [];
$links['edit'] = [];
if ($vid) {
$links['add']['#url'] = new Url('entity.gridstack_variant.ajax_add_form', $params, $options);
}
}
else {
$options = [
'language' => NULL,
'entity_type' => 'gridstack_variant',
'entity' => $variant,
];
$params['gridstack_variant'] = $params['vid'] = $variant
->id();
$links['duplicate']['#url'] = new Url('entity.gridstack_variant.ajax_edit_form', $params, $options);
unset($params['dup'], $params['vid']);
$links['delete']['#url'] = new Url('entity.gridstack_variant.ajax_delete_form', $params, $options);
$links['edit']['#url'] = new Url('entity.gridstack_variant.ajax_edit_form', $params, $options);
$params_cancel = $params;
$params_cancel['vid'] = $vid;
unset($params_cancel['gridstack_variant']);
$links['cancel']['#url'] = new Url('entity.gridstack_variant.ajax_cancel_form', $params_cancel, $options);
}
if ($this
->getVariants($name, $reload)) {
$options = [
'language' => NULL,
'entity_type' => 'gridstack',
'entity' => GridStack::loadWithFallback($name),
];
$params['vid'] = $vid;
unset($params['gridstack_variant']);
$links['select']['#url'] = new Url('entity.gridstack_variant.ajax_selection_form', $params, $options);
}
else {
$links['select'] = [];
}
return $links;
}
public function getVariantEditor(array $settings, $optionset, $reload = FALSE) {
$exists = $this->manager
->getModuleHandler()
->moduleExists('gridstack_ui');
$access = $this->currentUser
->hasPermission('modify gridstack variant');
if (!$exists || !$access) {
return [];
}
if (empty($settings['gid'])) {
return [];
}
$links = $this
->getVariantLinks($settings, $optionset, $reload);
$pos = $this
->config('editor_pos') == 'bottom' ? 'bottom' : 'top';
return $links ? [
'#type' => 'container',
'#attributes' => [
'class' => [
'gridstack-editor',
'gridstack-editor--' . $pos,
],
],
'#attached' => [
'library' => [
'core/drupal.ajax',
'gridstack/admin',
],
],
'form' => [
'#type' => 'container',
'#attributes' => [
'id' => GridStackDefault::variantWrapperId($settings['gid']),
'class' => [
'gridstack-editor__form',
'clearfix',
],
'data-gs-gid' => GridStackDefault::gid($settings['gid']),
],
'add' => $links['add'],
'edit' => $links['edit'],
'select' => $links['select'],
],
] : [];
}
public function getVariants($source, $reload = FALSE) {
if (!isset($this->variantOptions[$source]) || $reload) {
$options = [];
foreach ($this->manager
->entityLoadMultiple('gridstack_variant') as $key => $entity) {
if ($entity
->source() != $source) {
continue;
}
$options[$key] = Html::escape($entity
->label());
}
asort($options);
$this->variantOptions[$source] = $options;
}
return $this->variantOptions[$source];
}
}