View source
<?php
namespace Drupal\gridstack_ui\Form;
use Drupal\Core\Form\FormStateInterface;
use Drupal\gridstack\Entity\GridStack;
use Drupal\gridstack\Entity\GridStackVariant;
use Drupal\gridstack\GridStackDefault;
class GridStackVariantForm extends GridStackForm {
protected $isVariant = TRUE;
protected $niceName = 'GridStackVariant';
protected $machineName = 'gridstack_variant';
public function form(array $form, FormStateInterface $form_state) {
$form['#attributes']['class'][] = 'form--gridstack-variant';
$form['#attached']['library'][] = 'gridstack/admin_variant';
$source = $this->entity
->source();
$gridstack = $source ? GridStack::load($source) : NULL;
if ($source && $gridstack) {
$this
->setGridStack($gridstack);
}
$form = parent::form($form, $form_state);
if (!$this->entity
->source()) {
return [];
}
unset($form['options']['settings'], $form['options']['use_framework']);
$form['source'] = [
'#type' => 'hidden',
'#default_value' => $this->entity
->source(),
];
$description = $this
->t('Height is pre-determined by grids, not contents.');
if ($gridstack && $gridstack
->isFramework()) {
$description = $this
->t('Height is determined later by contents, not grids. Floating grid rules apply. Index order matters to float correctly.');
}
$id = $this->entity
->id();
$label = $this->entity
->label();
$pid = $gridstack ? $gridstack->id : NULL;
$form_wrapper_id = GridStackDefault::variantWrapperId($id);
$request_uri = $this
->getRequest()
->getRequestUri();
$parts = array_filter(explode('/', $request_uri));
$gid = NULL;
$pub = $this
->getRequest()->query
->get('pub', NULL);
$label_dup = $this
->getRequest()->query
->get('label', NULL);
$applied = !empty($pub) && $pub == $id;
$applied_differently = !empty($pub) && $pub != $id;
$variant_pub = $pub ? GridStackVariant::load($pub) : NULL;
$is_ajax = $parts[1] == 'gridstack';
if (isset($parts[4]) && $parts[3] == $source) {
$gid = $parts[4];
}
$links = [];
$config = [
'vid' => $id,
'optionset' => $pid,
'gid' => $gid,
'pub' => $pub,
];
$duplicated_vid = $form_state
->get('new_vid') ?: $this->entity
->getRandomizedId();
$input = $form_state
->getUserInput();
if (empty($duplicated_vid)) {
$duplicated_vid = isset($input['new_vid']) ? $input['new_vid'] : '';
}
if ($duplicated_vid) {
$config['dup'] = $duplicated_vid;
}
if ($gridstack && $gid) {
$links = $this->manager
->stylizer()
->builder($config)
->getVariantLinks($config, $gridstack);
}
$duplicate = isset($links['duplicate']) ? $links['duplicate'] : [];
if ($duplicate) {
$duplicate['#title'] = $this
->t('Save as New');
}
$form['#prefix'] = '<div id="' . $form_wrapper_id . '">';
$form['#suffix'] = '</div>';
$form['#attributes']['data-gs-gid'] = $gid;
$form['variant_actions'] = [
'#type' => 'container',
'#attributes' => [
'class' => [
'form--gridstack-variant__actions',
],
],
'#tree' => TRUE,
'#weight' => -100,
'#settings' => $config,
'#access' => $is_ajax,
'actions' => [
'#type' => 'container',
'#attributes' => [
'class' => [
'btn-group',
],
],
'close' => [
'#type' => 'button',
'#value' => $this
->t('Close'),
'#name' => 'close',
'#ajax' => [
'callback' => [
$this,
'closeVariant',
],
'effect' => 'fade',
'wrapper' => GridStackDefault::variantWrapperId($gid),
'progress' => [
'type' => 'throbber',
'message' => $this
->t('Closing.'),
],
],
'#attributes' => [
'class' => [
'btn',
'btn-dark',
'btn--variant-close',
],
],
],
'delete' => [
'#type' => 'button',
'#value' => $this
->t('Delete'),
'#name' => 'delete',
'#ajax' => [
'callback' => [
$this,
'deleteVariant',
],
'effect' => 'fade',
'wrapper' => $form_wrapper_id,
],
'#attributes' => [
'class' => [
'btn',
'btn-danger',
'btn--variant-delete',
],
'data-gs-vid' => '',
'data-gs-variant-ajax' => 'delete',
'data-gs-variant-message' => $this
->t('Deleting and reverting'),
],
],
'revert' => [
'#type' => 'button',
'#value' => $this
->t('Revert'),
'#name' => 'revert',
'#access' => $applied || $applied_differently,
'#ajax' => [
'callback' => [
$this,
'revertVariant',
],
'effect' => 'fade',
'wrapper' => $form_wrapper_id,
],
'#attributes' => [
'class' => [
'btn',
'btn-warning',
'btn--variant-revert',
],
'data-gs-vid' => '',
'data-gs-variant-ajax' => 'revert',
'data-gs-variant-message' => $this
->t('Reverting'),
],
],
'duplicate' => $duplicate,
'save' => [
'#type' => 'button',
'#value' => $this
->t('Save'),
'#name' => 'save',
'#ajax' => [
'callback' => [
$this,
'saveVariant',
],
'effect' => 'fade',
'wrapper' => GridStackDefault::variantWrapperId($gid),
'method' => 'html',
'progress' => [
'type' => 'throbber',
'message' => $this
->t('Saving.'),
],
],
'#attributes' => [
'class' => [
'btn',
'btn-success',
'btn--variant-save',
],
'data-gs-vid' => $id,
'data-gs-variant-nojs' => 'save',
'data-gs-variant-message' => $this
->t('Saving'),
'data-gs-update-icon' => 1,
],
],
'apply_trigger' => [
'#type' => 'submit',
'#value' => $this
->t('Apply'),
'#name' => 'apply_trigger',
'#attributes' => [
'class' => [
'btn',
'btn-success',
'btn--variant-apply-trigger',
],
'data-gs-vid' => $id,
'data-gs-variant-trigger' => 'apply',
'data-gs-variant-message' => $this
->t('Applying variant'),
'data-gs-update-icon' => 1,
],
],
'apply' => [
'#type' => 'button',
'#value' => $this
->t('Apply'),
'#name' => 'apply',
'#ajax' => [
'callback' => [
$this,
'saveVariant',
],
'effect' => 'fade',
'wrapper' => $form_wrapper_id,
'progress' => [
'type' => 'fullscreen',
'message' => $this
->t('Applying variant.'),
],
],
'#attributes' => [
'class' => [
'btn',
'btn--variant-apply',
'visually-hidden',
],
'data-gs-vid' => $id,
'data-gs-variant-ajax' => 'apply',
'data-gs-variant-message' => $this
->t('Applying'),
'data-gs-update-icon' => 1,
],
],
'select' => isset($links['select']) ? $links['select'] : [],
],
'update' => [
'#type' => 'submit',
'#value' => $this
->t('Update Icon'),
'#name' => 'update',
'#attributes' => [
'class' => [
'btn',
'btn-secondary',
'btn--variant-update',
],
'data-gs-vid' => $id,
'data-gs-variant-js' => 'update',
'data-gs-variant-message' => $this
->t('Updating'),
'data-gs-update-icon' => 1,
],
],
'description' => [
'#markup' => '<p><small>' . $description . '</small></p>',
'#allowed_tags' => [
'p',
'small',
],
],
];
$css = $this->manager
->stylizer()
->style()
->getVariantClass($label);
$label_suffix = $id;
if ($is_ajax) {
$label_suffix .= ' (';
$label_suffix .= $applied ? $this
->t('applied') : $this
->t('draft -- not applied');
if ($applied_differently && $variant_pub) {
$label_suffix .= $this
->t(', currently applied: @label', [
'@label' => $variant_pub
->label(),
]);
}
$label_suffix .= ')';
$form['actions']['#access'] = FALSE;
$form['description']['#access'] = FALSE;
unset($form['label']['#prefix'], $form['name']['#suffix']);
$form['label']['#attributes']['class'][] = 'form-text--label-variant';
if ($label_dup) {
$form_state
->setValue('label', $label_dup);
$form['label']['#default_value'] = $label_dup;
}
}
$form['name']['#machine_name']['source'] = [
'id',
];
$form['name']['#wrapper_attributes']['class'][] = 'visually-hidden';
$form['label']['#description'] = $this
->t('Label for this variant, also used as CSS class for unique styling: <code>@css</code>. <br>Changing a variant will change it everywhere else. To be unique, clone and give unique memorable label accordingly.', [
'@css' => $css,
]);
$form['label']['#field_suffix'] = $label_suffix;
$form['label']['#weight'] = -99;
$form['label']['#title_display'] = 'visually-hidden';
$form['label']['#attributes']['placeholder'] = $this
->t('Label');
if ($gridstack && ($uri = $gridstack
->getIconUri())) {
$icon = [
'#theme' => 'image',
'#uri' => $uri,
'#alt' => $this
->t('Thumbnail'),
];
if ($this
->currentUser()
->hasPermission('administer gridstack')) {
$image = $icon;
$icon = [
'#type' => 'link',
'#url' => $gridstack
->toUrl('edit-form'),
'#title' => [
'#markup' => $this->manager
->getRenderer()
->render($image),
'#allowed_tags' => [
'img',
],
],
];
}
$form['screenshot_original'] = [
'#type' => 'container',
'icon' => $icon,
'#weight' => 100,
'#attributes' => [
'class' => [
'form--gridstack__screenshot',
'form--gridstack__screenshot--original',
],
],
];
}
return $form;
}
public function closeVariant(array $form, FormStateInterface $form_state) {
$config = $form['variant_actions']['#settings'];
$gridstack = $this
->gridStack();
$editor = $this->manager
->stylizer()
->builder()
->getVariantEditor($config, $gridstack);
return $editor['form'];
}
public function deleteVariant(array $form, FormStateInterface $form_state) {
$this->entity
->delete();
return $form;
}
public function revertVariant(array $form, FormStateInterface $form_state) {
return $form;
}
public function duplicateVariant(array &$form, FormStateInterface $form_state) {
$entity = $this->entity;
$id = $entity
->getRandomizedId();
$form_state
->set('new_vid', $id);
$label = $form_state
->getValue('label') ?: $entity
->getLabelFromId($id);
$options = $entity
->getOptions();
unset($options['icon']);
$clone = $entity
->createDuplicateVariant($id, $label, $options);
$this
->setEntity($clone);
$this->entity
->save();
$id = $this->entity
->id();
$form['variant_actions']['actions']['duplicate']['#attributes']['disabled'] = TRUE;
$form['label']['#field_suffix'] = $id;
$this
->validateForm($form, $form_state);
$this
->save($form, $form_state);
$form_wrapper_id = GridStackDefault::variantWrapperId($id);
$form['#prefix'] = '<div id="' . $form_wrapper_id . '">';
foreach ([
'cancel',
'duplicate',
'revert',
'update',
'apply',
'save',
] as $key) {
$form['variant_actions']['actions'][$key]['#attributes']['data-gs-vid'] = $id;
if (!in_array($key, [
'cancel',
'update',
])) {
$form['variant_actions']['actions'][$key]['#ajax']['wrapper'] = $form_wrapper_id;
}
}
return $form;
}
public function saveVariant(array &$form, FormStateInterface &$form_state) {
$this
->validateForm($form, $form_state);
$this
->save($form, $form_state);
return $form;
}
protected function getApplicableBreakpoints() {
$gridstack = $this
->gridStack();
$breakpoints = $gridstack ? [
$gridstack
->getLastBreakpointKey(),
] : [
'lg',
];
$this->manager
->getModuleHandler()
->alter('gridstack_variant_applicable_breakpoints', $breakpoints, $gridstack, $this->engine, $this
->currentUser());
return $breakpoints;
}
public function buildEntity(array $form, FormStateInterface $form_state) {
$entity = parent::buildEntity($form, $form_state);
$request = $this
->getRequest();
$request_uri = $request
->getRequestUri();
$source = $entity
->source();
if (empty($source)) {
if ($this->operation == 'add' || $this->operation == 'duplicate') {
$args = array_filter(explode('/', $request_uri));
if (isset($args[3]) && $args[3] == 'gridstack') {
array_pop($args);
$source = end($args);
if ($gridstack = GridStack::load($source)) {
$entity
->set('source', $source);
$this
->setGridStack($gridstack);
}
}
}
}
return $entity;
}
public function save(array $form, FormStateInterface $form_state) {
$this->entity
->set('source', $this->entity
->source());
parent::save($form, $form_state);
}
}