View source
<?php
namespace Drupal\gridstack_ui\Form;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\gridstack\GridStackDefault;
use Drupal\gridstack\Entity\GridStack;
use Drupal\gridstack\Entity\GridStackVariant;
use Symfony\Component\DependencyInjection\ContainerInterface;
class GridStackVariantSelectionForm extends FormBase {
protected $optionset;
protected $manager;
public static function create(ContainerInterface $container) {
$instance = parent::create($container);
$instance
->setStringTranslation($container
->get('string_translation'));
$instance->manager = $container
->get('gridstack.manager');
return $instance;
}
public function getFormId() {
return 'gridstack_variant_selection_form';
}
public function buildForm(array $form, FormStateInterface $form_state) {
$args = $form_state
->getBuildInfo()['args'];
$name = $args[0];
$gid = $args[1];
$vid = $args[2];
$pub = $args[3];
if (!isset($this->optionset)) {
$this->optionset = GridStack::loadWithFallback($name);
}
$variants = $this->manager
->stylizer()
->builder()
->getVariants($name, TRUE);
$settings = [
'gid' => $gid,
'optionset' => $name,
'vid' => $vid,
'pub' => $pub,
];
$links = $this->manager
->stylizer()
->builder()
->getVariantLinks($settings, $this->optionset, TRUE);
$back = empty($links['edit']) ? [] : $links['edit'];
if ($back) {
$back['#title'] = $this
->t('Back');
}
$vid_wrapper_id = 'edit-vid-' . $gid;
$button_wrapper_id = 'edit-variant-actions-' . $gid;
$form_wrapper_id = GridStackDefault::variantWrapperId($gid);
$form['#attributes']['class'][] = 'form form--gridstack-variant-selection';
$form['container'] = [
'#type' => 'container',
'#attributes' => [
'class' => [
'btn-group',
],
],
'#prefix' => '<div id="' . $button_wrapper_id . '" class="form--gridstack-variant__actions">',
'#suffix' => '</div>',
'back' => $back,
'delete' => [
'#type' => 'button',
'#value' => $this
->t('Delete'),
'#ajax' => [
'callback' => '::deleteVariant',
'effect' => 'fade',
'wrapper' => $form_wrapper_id,
'method' => 'html',
],
'#attributes' => [
'class' => [
'btn',
'btn-danger',
'btn--variant-delete',
'visually-hidden',
],
'data-gs-vid' => '',
'data-gs-variant-ajax' => 'delete',
'data-gs-variant-message' => $this
->t('Deleting'),
],
'#limit_validation_errors' => [],
],
'edit' => [],
'cancel' => [
'#type' => 'button',
'#value' => $this
->t('Cancel'),
'#ajax' => [
'callback' => '::cancelSelection',
'effect' => 'fade',
'wrapper' => $form_wrapper_id,
],
'#attributes' => [
'class' => [
'btn',
'btn-warning',
'btn--selection-cancel',
],
],
],
];
$icons = [];
if ($uri = $this->optionset
->getIconUri()) {
$icons['base'] = [
'#theme' => 'image',
'#uri' => $uri,
'#alt' => $this
->t('Thumbnail'),
'#suffix' => $this
->t('@label <br>(original layout)', [
'@label' => $this->optionset
->label(),
]),
];
}
$form['icon'] = [
'#theme' => 'item_list',
'#items' => $icons,
'#wrapper_attributes' => [
'class' => [
'item-list--icon',
],
],
];
$form['vid'] = [
'#title' => $this
->t("Choose/ re-use an existing variant"),
'#type' => 'radios',
'#options' => $variants,
'#default_value' => '',
'#after_build' => [
[
$this,
'afterBuildSelection',
],
],
'#ajax' => [
'callback' => '::editVariant',
'wrapper' => $button_wrapper_id,
'method' => 'replace',
],
'#settings' => $settings,
'#prefix' => '<div id="' . $vid_wrapper_id . '" class="form-wrapper--selection">',
'#suffix' => '</div>',
];
return $form;
}
public function afterBuildSelection(array $element) {
$settings = $element['#settings'];
$removed = [
'form-wrapper--selection',
];
foreach (Element::children($element) as $key) {
if ($variant = GridStackVariant::load($key)) {
if ($uri = $variant
->getIconUri()) {
$token_query = [
IMAGE_DERIVATIVE_TOKEN => time(),
];
$image_url = \file_url_transform_relative(\file_create_url($uri));
$image_url .= (strpos($image_url, '?') !== FALSE ? '&' : '?') . UrlHelper::buildQuery($token_query);
$icon = [
'#theme' => 'image',
'#uri' => $image_url,
'#alt' => $this
->t('Thumbnail'),
];
$element[$key]['#field_suffix'] = $this->manager
->getRenderer()
->render($icon);
}
}
if (isset($element[$key]['#attributes']['class'])) {
$classes = $element[$key]['#attributes']['class'];
$classes = array_diff($classes, $removed);
$element[$key]['#attributes']['class'] = $classes;
}
$title = '';
if ($key == $settings['vid']) {
$element[$key]['#wrapper_attributes']['class'][] = 'was-gs-selected';
$title .= $this
->t('selected');
}
if ($key == $settings['pub']) {
$element[$key]['#wrapper_attributes']['class'][] = 'was-gs-selected is-gs-applied';
$title .= $this
->t('currently applied');
}
if ($key == $settings['pub'] && $key == $settings['vid']) {
$element[$key]['#wrapper_attributes']['class'][] = 'was-gs-selected is-gs-applied';
$title = $this
->t('selected, currently applied');
}
if ($title) {
$element[$key]['#title'] .= '<br>(' . $title . ')';
}
}
return $element;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
}
public function cancelSelection(array $form, FormStateInterface $form_state) {
$config = $form['vid']['#settings'];
$gridstack = $this->optionset;
$editor = $this->manager
->stylizer()
->builder()
->getVariantEditor($config, $gridstack);
return $editor['form'];
}
public function deleteVariant(array &$form, FormStateInterface $form_state) {
$vid = $form_state
->getValue('vid');
if ($vid && ($variant = GridStackVariant::load($vid))) {
$variant
->delete();
}
return $form;
}
public function editVariant(array &$form, FormStateInterface $form_state) {
$element = $form['container'];
$settings = $form['vid']['#settings'];
$vid = $settings['vid'] = $form_state
->getValue('vid');
if ($vid && GridStackVariant::load($vid)) {
$links = $this->manager
->stylizer()
->builder()
->getVariantLinks($settings, $this->optionset, TRUE);
if (!empty($links['edit'])) {
$element['edit'] = $links['edit'];
$classes = $element['delete']['#attributes']['class'];
$classes = array_diff($classes, [
'visually-hidden',
]);
$element['delete']['#attributes']['class'] = $classes;
}
}
else {
$element['back'] = [];
}
return $element;
}
}