View source
<?php
namespace Drupal\paragraphs_sets;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\paragraphs\Plugin\Field\FieldWidget\ParagraphsWidget;
class ParagraphsSets {
public static function getSets(array $allowed_paragraphs_types = []) {
$query = \Drupal::entityQuery('paragraphs_set');
$config_factory = \Drupal::configFactory();
$results = $query
->execute();
$sets = [];
foreach ($results as $id) {
if ($config = $config_factory
->get("paragraphs_sets.set.{$id}")) {
$data = $config
->get();
if (!empty($allowed_paragraphs_types)) {
$types_filtered = array_intersect(array_column($data['paragraphs'], 'type'), $allowed_paragraphs_types);
if (count($types_filtered) === count($data['paragraphs'])) {
$sets[$id] = $data;
}
}
}
}
return $sets;
}
public static function getSetsOptions(array $allowed_paragraphs_types = [], $cardinality = FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
$sets_data = static::getSets($allowed_paragraphs_types);
$opts = [];
foreach ($sets_data as $k => $set) {
if ($cardinality !== FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED && count($set['paragraphs']) > $cardinality) {
continue;
}
$opts[$k] = $set['label'];
}
return $opts;
}
public static function buildSelectSetSelection(array $elements, array $context, FormStateInterface $form_state, $default = NULL) {
$widget = $context['widget'];
if (!$widget instanceof ParagraphsWidget) {
return [];
}
$settings = $widget
->getThirdPartySettings('paragraphs_sets');
$items = $context['items'];
$field_definition = $items
->getFieldDefinition();
$field_name = $field_definition
->getName();
$title = $field_definition
->getLabel();
$cardinality = $field_definition
->getFieldStorageDefinition()
->getCardinality();
$field_parents = $context['form']['#parents'];
$field_id_prefix = implode('-', array_merge($field_parents, [
$field_name,
]));
$field_wrapper_id = Html::getId($field_id_prefix . '-add-more-wrapper');
$field_state = static::getWidgetState($field_parents, $field_name, $form_state);
$field_allowed_paragraphs_types = $widget
->getAllowedTypes($field_definition);
$options = static::getSetsOptions(array_keys($field_allowed_paragraphs_types), $cardinality);
if (isset($settings['paragraphs_sets']['sets_allowed']) && count(array_filter($settings['paragraphs_sets']['sets_allowed']))) {
$options = array_intersect_key($options, array_filter($settings['paragraphs_sets']['sets_allowed']));
}
$options = [
'_none' => t('- None -'),
] + $options;
$selection_elements = [
'#type' => 'container',
'#theme_wrappers' => [
'container',
],
'#attributes' => [
'class' => [
'set-selection-wrapper',
],
],
];
$selection_elements['set_selection_select'] = [
'#type' => 'select',
'#options' => $options,
'#default_value' => $default,
'#title' => t('@title set', [
'@title' => $widget
->getSetting('title'),
]),
'#label_display' => 'hidden',
];
$selection_elements['set_selection_button'] = [
'#type' => 'submit',
'#name' => strtr($field_id_prefix, '-', '_') . '_set_selection',
'#value' => t('Select set'),
'#attributes' => [
'class' => [
'field-set-selection-submit',
],
],
'#limit_validation_errors' => [
array_merge($field_parents, [
$field_name,
'set_selection',
]),
],
'#submit' => [
[
'\\Drupal\\paragraphs_sets\\ParagraphsSets',
'setSetSubmit',
],
],
'#ajax' => [
'callback' => [
'\\Drupal\\paragraphs_sets\\ParagraphsSets',
'setSetAjax',
],
'wrapper' => $field_wrapper_id,
'effect' => 'fade',
],
];
$selection_elements['set_selection_button']['#prefix'] = '<div class="paragraphs-set-button paragraphs-set-button-set">';
$selection_elements['set_selection_button']['#suffix'] = t('for %type', [
'%type' => $title,
]) . '</div>';
if ($field_state['items_count'] && ($field_state['items_count'] < $cardinality || $cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) && !$form_state
->isProgrammed() && (isset($elements['#allow_reference_changes']) && $elements['#allow_reference_changes'])) {
$selection_elements['append_selection_button'] = [
'#type' => 'submit',
'#name' => strtr($field_id_prefix, '-', '_') . '_append_selection',
'#value' => t('Append set'),
'#attributes' => [
'class' => [
'field-append-selection-submit',
],
],
'#limit_validation_errors' => [
array_merge($field_parents, [
$field_name,
'append_selection',
]),
],
'#submit' => [
[
'\\Drupal\\paragraphs_sets\\ParagraphsSets',
'setSetSubmit',
],
],
'#ajax' => [
'callback' => [
'\\Drupal\\paragraphs_sets\\ParagraphsSets',
'setSetAjax',
],
'wrapper' => $field_wrapper_id,
'effect' => 'fade',
],
];
$selection_elements['append_selection_button']['#prefix'] = '<div class="paragraphs-set-button paragraphs-set-button-append">';
$selection_elements['append_selection_button']['#suffix'] = t('to %type', [
'%type' => $title,
]) . '</div>';
}
return $selection_elements;
}
public static function getWidgetState(array $parents, $field_name, FormStateInterface $form_state) {
return NestedArray::getValue($form_state
->getStorage(), static::getWidgetStateParents($parents, $field_name));
}
public static function setWidgetState(array $parents, $field_name, FormStateInterface $form_state, array $field_state) {
NestedArray::setValue($form_state
->getStorage(), static::getWidgetStateParents($parents, $field_name), $field_state);
}
public static function getWidgetStateParents(array $parents, $field_name) {
return array_merge([
'field_storage',
'#parents',
], $parents, [
'#fields',
$field_name,
]);
}
public static function setSetAjax(array $form, FormStateInterface $form_state) {
$button = $form_state
->getTriggeringElement();
$element = NestedArray::getValue($form, array_slice($button['#array_parents'], 0, -2));
return $element;
}
public static function setSetSubmit(array $form, FormStateInterface $form_state) {
$button = $form_state
->getTriggeringElement();
$element = NestedArray::getValue($form, array_slice($button['#array_parents'], 0, -2));
$field_name = $element['#field_name'];
$parents = $element['#field_parents'];
$button_type = end($button['#array_parents']);
$widget_state = static::getWidgetState($parents, $field_name, $form_state);
$widget_state['button_type'] = $button_type;
if (isset($button['#set_machine_name'])) {
$widget_state['selected_set'] = $button['#set_machine_name'];
}
else {
$widget_state['selected_set'] = $element['set_selection']['set_selection_select']['#value'];
}
static::setWidgetState($parents, $field_name, $form_state, $widget_state);
$form_state
->setRebuild();
}
public static function prepareDeltaPosition(array &$widget_state, FormStateInterface $form_state, array $field_path, $new_delta) {
$widget_state['items_count']++;
if (!is_numeric($new_delta) || intval($new_delta) >= $widget_state['real_item_count']) {
return;
}
$widget_state['real_item_count']++;
$new_delta = max(intval($new_delta), 0);
$user_input = NestedArray::getValue($form_state
->getUserInput(), $field_path);
$new_original_deltas = [];
foreach ($widget_state['original_deltas'] as $current_delta => $original_delta) {
$new_current_delta = $current_delta >= $new_delta ? $current_delta + 1 : $current_delta;
$new_original_deltas[$new_current_delta] = $original_delta;
$user_input[$original_delta]['_weight'] = $new_current_delta;
}
$original_deltas_size = count($widget_state['original_deltas']);
$new_original_deltas[$new_delta] = $original_deltas_size;
$user_input[$original_deltas_size]['_weight'] = $new_delta;
$widget_state['original_deltas'] = $new_original_deltas;
NestedArray::setValue($form_state
->getUserInput(), $field_path, $user_input);
}
public static function inTranslation(FormStateInterface $form_state, EntityInterface $host) {
$is_in_translation = FALSE;
if (!$host
->isTranslatable()) {
return FALSE;
}
if (!$host
->getEntityType()
->hasKey('default_langcode')) {
return FALSE;
}
$default_langcode_key = $host
->getEntityType()
->getKey('default_langcode');
if (!$host
->hasField($default_langcode_key)) {
return FALSE;
}
if (!empty($form_state
->get('content_translation'))) {
$is_in_translation = TRUE;
}
if ($host
->hasTranslation($form_state
->get('langcode')) && $host
->getTranslation($form_state
->get('langcode'))
->get($default_langcode_key)->value == 0) {
$is_in_translation = TRUE;
}
return $is_in_translation;
}
}