View source
<?php
namespace Drupal\gridstack\Plugin\gridstack\stylizer;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Form\FormStateInterface;
use Drupal\gridstack\GridStackDefault;
use Drupal\gridstack\Entity\GridStackVariant;
class Form extends Help {
public function buildConfigurationForm($optionset, FormStateInterface $form_state, array $settings, array $extras = []) {
$context = $settings['_scope'];
$element = [];
if ($context == GridStackDefault::ROOT) {
$settings['_fullwidth'] = TRUE;
$element = array_merge($element, $this
->globalForm($optionset, $form_state, $settings, $extras));
}
$element = array_merge($element, $this
->wrapperForm($optionset, $form_state, $settings, $extras));
foreach ([
'target_id',
'_fullwidth',
] as $key) {
$element[$key]['#type'] = 'hidden';
$element[$key]['#default_value'] = isset($settings[$key]) ? $settings[$key] : '';
}
$element['target_id']['#attributes']['data-gs-media-storage'] = $context;
$element = array_merge($element, $this
->styleForm($optionset, $form_state, $settings, $extras));
return $element;
}
public function closingForm(array &$form, array $settings) {
$form['current_selection'] = [
'#type' => 'hidden',
'#default_value' => '',
'#attributes' => [
'class' => [
'js-media-library-add-form-current-selection',
],
],
];
if ($palettes = $this
->getColorPalettes()) {
$form['color_palettes'] = $this
->paletteElement($palettes);
if ($pos = $this
->config('palettes_pos')) {
$form['color_palettes']['#attributes']['class'][] = 'form-wrapper--color-palettes--offset';
$form['color_palettes']['#attributes']['class'][] = 'form-wrapper--color-palettes--' . $pos;
}
}
if (!$this
->config('helpless')) {
$form['help'] = [];
$form['help'] = array_merge($form['help'], $this
->helpElement());
}
$form['#attached']['library'][] = 'gridstack/admin_modal';
if (!empty($settings['access_media']) && ($library = $this
->getMediaLibraryTheme())) {
$form['#attached']['library'][] = $library;
}
}
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
parent::validateConfigurationForm($form, $form_state);
$settings = $form_state
->getValue('settings');
$form_state
->setValue([
'settings',
'gridnative',
], (bool) $settings['gridnative']);
$form_state
->setValue([
'settings',
'_fullwidth',
], (bool) $settings['_fullwidth']);
$key = [
'settings',
'wrapper_classes',
];
$this
->massageClasses($key, $settings, $form_state);
$key = [
'settings',
'row_classes',
];
$this
->massageRowClasses($key, $settings, $form_state);
$key = [
'settings',
'styles',
'metadata',
];
$this
->massageMetadata($key, $settings, $form_state);
foreach ([
'animations',
'colors',
'extras',
] as $key) {
$setting_name = [
'settings',
'styles',
$key,
];
$this
->massageArrayValues($key, $setting_name, $form_state);
}
$regions = $form_state
->getValue('regions');
foreach ($regions as $name => $region) {
$form_state
->setValue([
'regions',
$name,
'_fullwidth',
], (bool) $region['_fullwidth']);
$key = [
'regions',
$name,
'wrapper_classes',
];
$this
->massageClasses($key, $region, $form_state);
$key = [
'regions',
$name,
'row_classes',
];
$this
->massageRowClasses($key, $region, $form_state);
$key = [
'regions',
$name,
'styles',
'metadata',
];
$this
->massageMetadata($key, $region, $form_state);
foreach ([
'animations',
'colors',
'extras',
] as $key) {
$setting_name = [
'regions',
$name,
'styles',
$key,
];
$this
->massageArrayValues($key, $setting_name, $form_state);
}
}
}
protected function massageMetadata($key, array $settings, FormStateInterface $form_state) {
$mid = $this
->saveMediaId($settings, $form_state);
$data = $this
->getMediaData(NULL, $mid);
$form_state
->setValue($key, $data ? Json::encode($data) : '');
}
protected function massageArrayValues($key, array $name, FormStateInterface $form_state) {
$values = $form_state
->getValue($name);
if ($key == 'colors') {
foreach ($values as &$value) {
if ($value == "#000000") {
$value = '';
}
}
}
$form_state
->setValue($name, array_filter($values));
}
public function cleanupStyles(array &$settings = []) {
$data = [
'open_button',
'media_library_update_widget',
'media_library_selection',
'remove_button',
'selection',
];
foreach ($data as $key) {
unset($settings[$key]);
}
}
protected function massageClasses($name, array $settings, FormStateInterface $form_state) {
$wrapper_class = isset($settings['wrapper_classes']) ? $settings['wrapper_classes'] : '';
$selected_classes = isset($settings['preset_classes']) ? $settings['preset_classes'] : [];
$classes = [];
if ($classes = $this->manager
->getMergedClasses(TRUE)) {
$classes = array_combine($classes, $classes);
}
$this
->massageAllClasses($form_state, $name, $wrapper_class, $selected_classes, $classes);
}
protected function massageRowClasses($name, array $settings, FormStateInterface $form_state) {
$wrapper_class = isset($settings['row_classes']) ? $settings['row_classes'] : '';
$selected_classes = isset($settings['preset_row_classes']) ? $settings['preset_row_classes'] : [];
$classes = [];
if ($classes = $this->manager
->engineManager()
->getClassOptions('row')) {
$classes = array_combine($classes, $classes);
}
$this
->massageAllClasses($form_state, $name, $wrapper_class, $selected_classes, $classes);
}
protected function massageAllClasses(FormStateInterface $form_state, $name, $wrapper_class = '', array $selected_classes = [], array $classes = []) {
$wrapper_classes = $wrapper_class ? array_map('trim', explode(" ", $wrapper_class)) : [];
$wrapper_classes = $wrapper_class ? array_combine($wrapper_classes, $wrapper_classes) : [];
$selected_classes = array_filter($selected_classes);
if ($selected_classes) {
$selected_classes = array_values($selected_classes);
$selected_classes = array_combine($selected_classes, $selected_classes);
}
if ($wrapper_classes) {
foreach ($wrapper_classes as $key => $value) {
if (isset($classes[$key]) && !isset($selected_classes[$key])) {
unset($wrapper_classes[$key]);
}
}
}
$wrapper_classes = $selected_classes ? array_merge($wrapper_classes, $selected_classes) : $wrapper_classes;
$wrapper_classes = array_unique(array_values($wrapper_classes));
$merged = $wrapper_classes ? implode(" ", $wrapper_classes) : '';
$form_state
->setValue($name, $merged);
}
protected function globalForm($optionset, FormStateInterface $form_state, array $settings, array $extras = []) {
$element = [];
$field_options = $extras['field_options'];
$framework = $optionset
->isFramework();
$vid = $this
->getVariantUniqueId($optionset);
if (empty($settings['vid']) && GridStackVariant::load($vid)) {
$vid = $this
->getVariantUniqueId($optionset);
}
$element['global'] = [
'#type' => 'details',
'#open' => FALSE,
'#title' => $this
->t('Main settings'),
];
if (!$this
->config('skinless')) {
$element['global']['skin'] = [
'#type' => 'select',
'#title' => $this
->t('Skin'),
'#options' => $this->manager
->skinManager()
->getSkinOptions(),
'#empty_option' => $this
->t('- None -'),
'#default_value' => $settings['skin'],
];
}
$empty_desc = $field_options ? '' : ' ' . $this
->t('Create one unlimited multi-value Media if none exists.');
$element['global']['field_name'] = [
'#type' => 'select',
'#title' => $this
->t('Media field'),
'#options' => $field_options,
'#empty_option' => $this
->t('- None -'),
'#description' => $this
->t('Unlimited <code>Media</code> field to select media from.') . $empty_desc,
'#default_value' => $settings['field_name'],
];
$element['global']['vm'] = [
'#type' => 'select',
'#title' => $this
->t('Vertical margin'),
'#options' => GridStackDefault::breakpoints(),
'#empty_option' => $this
->t('- None -'),
'#description' => $this
->t('Avoid overlapping regions globally, unless desired. If bad, use region settings instead.'),
'#default_value' => $settings['vm'],
'#access' => !empty($framework),
'#attributes' => [
'class' => [
'form-item--vm',
],
],
];
$element['global']['gridnative'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Use native CSS Grid'),
'#description' => $this
->t('<b>Experimental!</b> Check to replace any js-driven (gridstack, masonry, packery, isotope) layouts with native browser Grid layout. Check out <a href=":url">CSS Grid browser supports</a> relevant to your visitors. Uncheck if any issue.', [
':url' => 'https://caniuse.com/#feat=css-grid',
]),
'#default_value' => $settings['gridnative'],
'#access' => empty($framework),
];
$icons = [];
$element['global']['icon']['#theme'] = 'item_list';
$element['global']['icon']['#wrapper_attributes']['class'][] = 'item-list--icon';
if ($uri = $optionset
->getIconUri()) {
$icons['base'] = [
'#theme' => 'image',
'#uri' => $uri,
'#alt' => $this
->t('Thumbnail'),
];
}
if (!empty($settings['vid']) && ($variant = GridStackVariant::load($settings['vid']))) {
if ($uri = $variant
->getIconUri()) {
$icons['base']['#suffix'] = $this
->t('Original layout');
$icons['variant'] = [
'#theme' => 'image',
'#uri' => $uri,
'#alt' => $this
->t('Thumbnail'),
'#suffix' => $this
->t('Variant @label', [
'@label' => $variant
->label(),
]),
];
$element['global']['icon']['#attributes']['class'][] = 'form-wrapper--icon';
}
}
$element['global']['icon']['#items'] = $icons;
$element['global']['vid'] = [
'#type' => 'hidden',
'#default_value' => empty($settings['vid']) ? $vid : $settings['vid'],
];
$element['global']['gid'] = [
'#type' => 'hidden',
'#default_value' => empty($settings['gid']) ? $optionset
->id() . ':' . $optionset
->randomize(4) : $settings['gid'],
];
$entity = $extras;
unset($entity['entity'], $entity['field_options']);
$element['global']['metadata'] = [
'#type' => 'hidden',
'#default_value' => $extras ? Json::encode($entity) : '',
];
return $element;
}
protected function wrapperForm($optionset, FormStateInterface $form_state, array $settings, array $extras = []) {
$element = [];
$context = $settings['_scope'];
$desc = $context == GridStackDefault::ROOT ? $this
->t('Affecting all. To refine, use region settings.') : '';
$element['wrappers'] = [
'#type' => 'details',
'#open' => FALSE,
'#tree' => FALSE,
'#title' => $this
->t('Wrappers'),
'#attributes' => [
'class' => [
'form-wrapper--wrappers',
],
],
];
$element['wrappers'] = array_merge($element['wrappers'], $this
->wrapperElement($optionset, $form_state, $settings, $extras));
$element['preset_classes'] = [
'#type' => 'details',
'#open' => FALSE,
'#tree' => TRUE,
'#title' => $this
->t('Generic preset classes'),
'#description' => $this
->t('Merged with <code>Classes</code> once saved. Leave any color empty for <code>Styles</code> to work.') . ' ' . $desc,
'#attributes' => [
'class' => [
'form-wrapper--preset-classes',
],
],
'#region' => $context,
];
$element['preset_classes'] = array_merge($element['preset_classes'], $this
->classesElement($optionset, $form_state, $settings, $extras));
$element['preset_row_classes'] = [
'#type' => 'details',
'#open' => FALSE,
'#tree' => TRUE,
'#title' => $this
->t('Row preset classes'),
'#description' => $this
->t('Merged with <code>Row classes</code> once saved.') . ' ' . $desc,
'#attributes' => [
'class' => [
'form-wrapper--preset-classes',
],
],
'#region' => $context,
'#access' => $optionset
->isFramework() && !empty($settings['_container']),
];
$element['preset_row_classes'] = array_merge($element['preset_row_classes'], $this
->rowClassesElement($optionset, $form_state, $settings, $extras));
return $element;
}
protected function styleForm($optionset, FormStateInterface $form_state, array $settings, array $extras = []) {
$element = [];
$styles = $settings;
$context = $settings['_scope'];
foreach (GridStackDefault::styleSettings() as $key => $value) {
$default = isset($settings['styles'][$key]) ? $settings['styles'][$key] : $value;
if ($context == GridStackDefault::ROOT) {
$name = [
'settings',
'styles',
$key,
];
}
else {
$name = [
'regions',
$context,
'styles',
$key,
];
}
$styles[$key] = $form_state
->getValue($name, $default);
}
$element['styles'] = [
'#type' => 'details',
'#tree' => TRUE,
'#title' => $this
->t('Styles'),
];
$exists = $this->manager
->getModuleHandler()
->moduleExists('media_library');
if ($exists && !empty($settings['field_name'])) {
$styles['field_name'] = $settings['field_name'];
if ($options = $this
->getResponsiveImageOptions()) {
$value = isset($styles['responsive_image_style']) ? $styles['responsive_image_style'] : '';
$element['styles']['responsive_image_style'] = [
'#type' => 'select',
'#title' => $this
->t('Responsive Image'),
'#options' => $options,
'#empty_option' => $this
->t('- None -'),
'#default_value' => $value,
'#wrapper_attributes' => [
'class' => [
'form-item--resimage',
],
],
];
}
if (!empty($settings['access_media'])) {
$this
->mediaElement($element['styles'], $optionset, $form_state, $styles, $extras);
}
}
$element['styles'] = array_merge($element['styles'], $this
->rangeElement($styles));
$element['styles']['colors'] = [];
$element['styles']['colors'] = array_merge($element['styles']['colors'], $this
->colorElement($optionset, $form_state, $styles, $extras));
$element['styles']['extras'] = [];
$element['styles']['extras'] = array_merge($element['styles']['extras'], $this
->extrasElement($optionset, $form_state, $styles, $extras));
if (!$this
->config('animationless')) {
$element['styles']['animations'] = [];
$element['styles']['animations'] = array_merge($element['styles']['animations'], $this
->animationElement($optionset, $form_state, $styles, $extras));
}
return $element;
}
private function getColorPalettes() {
$colors = [];
if ($palettes = $this
->config('palettes')) {
$palettes = array_map('trim', explode("\n", $palettes));
foreach ($palettes as $palette) {
if (strpos($palette, '|') !== FALSE) {
list($group, $group_color) = array_pad(array_map('trim', explode("|", $palette, 2)), 2, NULL);
$group_colors = array_map('trim', explode(" ", $group_color));
$colors[$group] = array_unique($group_colors);
}
}
}
return $colors;
}
}