View source
<?php
namespace Drupal\viewsreference\Plugin\Field\FieldWidget;
use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Utility\Html;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\views\Views;
use Drupal\Core\Form\FormStateInterface;
trait ViewsReferenceTrait {
public function fieldElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$field_name = $this->fieldDefinition
->getName();
$field_parents = [];
if (isset($element['#field_parents'])) {
$field_parents = $element['#field_parents'];
}
elseif (isset($element['target_id']['#field_parents'])) {
$field_parents = $element['target_id']['#field_parents'];
}
$field_path = array_merge($field_parents, [
$field_name,
$delta,
]);
$target_id_field_path = array_merge($field_path, [
'target_id',
]);
$field_value = $this
->itemCurrentValues($items, $delta, $element, $form, $form_state);
switch ($element['target_id']['#type']) {
case 'select':
$view_selected_js_state = [
'!value' => '_none',
];
$ajax_event = 'change';
$element['target_id']['#default_value'] = isset($field_value['target_id']) ? $field_value['target_id'] : '';
break;
default:
$view_selected_js_state = [
'filled' => TRUE,
];
$ajax_event = 'viewsreference-select';
break;
}
$target_id_names = $target_id_field_path;
$target_id_name_string = array_shift($target_id_names);
foreach ($target_id_names as $target_id_name) {
$target_id_name_string .= '[' . $target_id_name . ']';
}
$html_wrapper_id = Html::getUniqueId(implode('-', $field_path));
$class = get_class($this);
$element['target_id']['#target_type'] = 'view';
$element['target_id']['#limit_validation_errors'] = [];
$element['target_id']['#ajax'] = [
'callback' => [
$class,
'itemAjaxRefresh',
],
'event' => $ajax_event,
'wrapper' => $html_wrapper_id,
'progress' => [
'type' => 'throbber',
'message' => $this
->t('Getting display IDs...'),
],
];
$display_id = $field_value['display_id'] ?? NULL;
$view_name = $field_value['target_id'] ?? NULL;
$options = [];
if ($view_name) {
preg_match('#\\((.*?)\\)#', $view_name, $match);
if (!empty($match)) {
$view_name = $match[1];
}
$options = $this
->getViewDisplays($view_name);
}
$element['display_id'] = [
'#title' => $this
->t('Display'),
'#type' => 'select',
'#options' => $options,
'#default_value' => $display_id,
'#empty_option' => $this
->t('- Select -'),
'#empty_value' => '',
'#weight' => 10,
'#attributes' => [
'class' => [
'viewsreference-display-id',
],
],
'#states' => [
'visible' => [
':input[name="' . $target_id_name_string . '"]' => $view_selected_js_state,
],
'required' => [
':input[name="' . $target_id_name_string . '"]' => $view_selected_js_state,
],
],
'#ajax' => [
'callback' => [
$class,
'itemAjaxRefresh',
],
'event' => $ajax_event,
'wrapper' => $html_wrapper_id,
'progress' => [
'type' => 'throbber',
'message' => $this
->t('Getting options...'),
],
],
];
$field_data = [];
if (isset($field_value['data'])) {
$field_data = unserialize($field_value['data'], [
'allowed_classes' => FALSE,
]);
}
$element['options'] = [
'#type' => 'details',
'#title' => $this
->t('Options'),
'#weight' => 10,
'#states' => [
'visible' => [
':input[name="' . $target_id_name_string . '"]' => $view_selected_js_state,
],
],
];
$viewsreference_plugin_manager = \Drupal::service('plugin.manager.viewsreference.setting');
$plugin_definitions = $viewsreference_plugin_manager
->getDefinitions();
$enabled_settings = array_filter($this
->getFieldSetting('enabled_settings') ?? []);
foreach ($enabled_settings as $enabled_setting) {
if (!empty($plugin_definitions[$enabled_setting])) {
$plugin_definition = $plugin_definitions[$enabled_setting];
$plugin_instance = $viewsreference_plugin_manager
->createInstance($plugin_definition['id'], [
'view_name' => $view_name,
'display_id' => $display_id,
]);
$element['options'][$plugin_definition['id']] = [
'#title' => $plugin_definition['label'],
'#type' => 'textfield',
'#default_value' => $field_data[$plugin_definition['id']] ?? $plugin_definition['default_value'],
'#states' => [
'visible' => [
':input[name="' . $target_id_name_string . '"]' => $view_selected_js_state,
],
],
];
$plugin_instance
->alterFormField($element['options'][$plugin_definition['id']]);
}
}
if (empty($enabled_settings)) {
unset($element['options']);
}
$element['#attached']['library'][] = 'viewsreference/viewsreference';
$element['#after_build'][] = [
$class,
'itemResetValues',
];
$element = [
'#prefix' => '<div id="' . $html_wrapper_id . '">',
'#suffix' => '</div>',
'#wrapper_id' => $html_wrapper_id,
] + $element;
return $element;
}
public function itemCurrentValues(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$values = [];
$field_name = $this->fieldDefinition
->getName();
$value_parents = [];
if (isset($element['#field_parents'])) {
$value_parents = $element['#field_parents'];
}
elseif (isset($element['target_id']['#field_parents'])) {
$value_parents = $element['target_id']['#field_parents'];
}
$value_parents = array_merge($value_parents, [
$field_name,
$delta,
]);
$form_input_values = $form_state
->getUserInput();
$input_value_exists = NULL;
if ($form_input_values) {
$input_values = NestedArray::getValue($form_input_values, $value_parents, $input_value_exists);
if ($input_value_exists) {
$values = $input_values;
}
}
if (!$input_value_exists) {
if ($item_state_values = $form_state
->getValue($value_parents)) {
$values = $item_state_values;
}
elseif ($item_values = $items[$delta]
->getValue()) {
$values = $item_values;
}
}
return $values;
}
public static function itemResetValues(array $element, FormStateInterface $form_state) {
$triggering_element = $form_state
->getTriggeringElement();
if (!$triggering_element) {
return $element;
}
$keys = [
'target_id' => [
'display_id',
],
];
$triggering_element_name = end($triggering_element['#parents']);
if (isset($keys[$triggering_element_name])) {
$input =& $form_state
->getUserInput();
foreach ($keys[$triggering_element_name] as $key) {
$parents = array_merge($element['#parents'], [
$key,
]);
NestedArray::setValue($input, $parents, '');
$element[$key]['#value'] = '';
}
}
return $element;
}
public static function itemAjaxRefresh(array $form, FormStateInterface $form_state) {
$triggering_element = $form_state
->getTriggeringElement();
$parents = $triggering_element['#array_parents'];
array_pop($parents);
return NestedArray::getValue($form, $parents);
}
protected function getAllViewsDisplayIds() {
$views = Views::getAllViews();
$options = [];
foreach ($views as $view) {
if ($displays = $view
->get('display')) {
foreach ($displays as $display) {
$options[$display['id']] = $display['display_title'];
}
}
}
return $options;
}
protected function getViewDisplays($view_id) {
$options = [];
$view_plugins = array_diff($this
->getFieldSetting('plugin_types'), [
'0',
]);
if ($view = \Drupal::service('entity_type.manager')
->getStorage('view')
->load($view_id)) {
if ($displays = $view
->get('display')) {
usort($displays, function ($a, $b) {
return $a['position'] <=> $b['position'];
});
foreach ($displays as $display) {
if (in_array($display['display_plugin'], $view_plugins, TRUE)) {
$options[$display['id']] = $display['display_title'];
}
}
}
}
return $options;
}
protected function getViewNames(array $views_array) {
$views_list = [];
foreach ($views_array as $key => $value) {
if ($view = Views::getView($key)) {
$views_list[$view->storage
->id()] = $view->storage
->label();
}
}
return $views_list;
}
public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
$values = parent::massageFormValues($values, $form, $form_state);
foreach ($values as $key => $value) {
if (isset($value['options']) && is_array($value['options'])) {
foreach ($value['options'] as $ind => $option) {
$values[$key][$ind] = $option;
}
unset($value['options']);
}
}
$values = $this
->serializeSettingsValues($values);
return $values;
}
protected function serializeSettingsValues(array $values) {
$viewsreference_plugin_manager = \Drupal::service('plugin.manager.viewsreference.setting');
$plugin_definitions = $viewsreference_plugin_manager
->getDefinitions();
foreach ($values as $delta => $value) {
$serialized_fields = [];
foreach ($plugin_definitions as $plugin_definition) {
$serialized_fields[$plugin_definition['id']] = isset($value[$plugin_definition['id']]) ? $value[$plugin_definition['id']] : NULL;
unset($values[$delta][$plugin_definition['id']]);
}
$values[$delta]['data'] = serialize($serialized_fields);
}
return $values;
}
}