degov-8.x-2.0/modules/degov_paragraph_view_reference/degov_paragraph_view_reference.module
modules/degov_paragraph_view_reference/degov_paragraph_view_reference.module
<?php
use Drupal\degov_common\Common;
/**
* Implements hook_preprocess().
*/
function degov_paragraph_view_reference_preprocess(&$variables, $hook, &$info) {
// Add template suggestions and libraries implemented in this module.
Common::addThemeSuggestions($variables, $hook, $info, [
'module_name' => 'degov_paragraph_view_reference',
'entity_type' => 'paragraph',
'entity_bundles' => ['view_reference'],
'entity_view_modes' => ['default', 'preview'],
]);
}
/**
* Implements hook_field_info_alter().
*/
function degov_paragraph_view_reference_field_info_alter(&$info) {
// Change the class for viewsreference field type.
if (isset($info['viewsreference'])) {
$info['viewsreference']['class'] = 'Drupal\degov_paragraph_view_reference\Plugin\Field\FieldType\ViewsReferenceOverride';
}
}
/**
* HELPER FUNCTIONS FOR viewsreference module.
*/
/**
* Get the correct nested form element name.
*
* @param $dependee
* @param $element
* @param $field_definition
*
* @return string
*/
function _views_selector_get_state_name($dependee, $element, $field_definition) {
$selector = $element['target_id']['#field_parents'];
$selector[] = $field_definition->get('field_name');
$selector[] = '0';
$selector[] = $dependee;
$start = array_shift($selector);
return $start . '[' . implode('][', $selector) . ']';
}
/**
* Returns the field value on ajax callback event change.
*
* @param array $form
* @param \Drupal\Core\Form\FormStateInterface $form_state
*
* @return array
*/
function degov_views_argument_getter(array &$form, \Drupal\Core\Form\FormStateInterface $form_state) {
$trigger = $form_state->getTriggeringElement();
$parents = $trigger['#array_parents'];
$triggered_element = array_pop($parents);
$parents[] = 'options';
return \Drupal\Component\Utility\NestedArray::getValue($form, $parents);
}
/**
* Retrieves the field info by given contextual filter.
*
* @param $argument
*
* @return array
*/
function _views_argument_field_info($argument) {
$info = FALSE;
if (!empty($argument['table'])) {
$keys = explode('__', $argument['table']);
if (!empty($keys)) {
$info = \Drupal\field\Entity\FieldStorageConfig::loadByName($keys[0], $keys[1]);
// if it is entity reference field try to get the target type and selector settings
if ($info && $info->getType() == 'entity_reference') {
$bundles = $info->getBundles();
$bundles_machine_names = array_keys($bundles);
$bundle_info = \Drupal\field\Entity\FieldConfig::loadByName($keys[0], $bundles_machine_names[0], $keys[1]);
}
else {
$bundle_info = [];
}
}
}
return ['info' => $info, 'bundle_info' => $bundle_info];
}
/**
* @param $element
* @param \Drupal\Core\Form\FormStateInterface $form_state
* @param $context
*/
function degov_paragraph_view_reference_field_widget_form_alter(&$element, \Drupal\Core\Form\FormStateInterface $form_state, $context) {
/** @var \Drupal\Core\Field\EntityReferenceFieldItemList $items */
$items = $context['items'];
// Get the field definition.
$field_definition = $items->getFieldDefinition();
if ($field_definition->getType() == 'viewsreference') {
// Get configuration settings for the form widget.
$config = \Drupal::service('config.factory')
->getEditable('degov_paragraph_view_reference.views_helper_settings');
$allowed_forms = $config->get('form_ids');
// Get the form renderer array.
$form = $form_state->getCompleteForm();
// If the form is within the allowed ones - alter.
if (in_array($form['#form_id'], $allowed_forms)) {
// Get the allowed views list.
$allowed_views = $config->get('allowed_views');
// Loop through the element options and remove not allowed.
foreach ($element['target_id']['#options'] as $key => $view_name) {
if (empty($allowed_views[$key])) {
unset($element['target_id']['#options'][$key]);
}
}
}
$element['options']['title']['#access'] = FALSE;
// Create the selector for the arguments fields for the ajax response.
$arguments_wrapper_selector = implode('_', $element['target_id']['#field_parents']) . '_arguments';
$arguments_weight = !empty($element['options']['argument']['#weight']) ? $element['options']['argument']['#weight'] : 10;
// Add empty option and ajax callback for the display_id field.
$element['display_id']['#options'] = ['_none' => t('-- Choose view display --')] + $element['display_id']['#options'];
$element['display_id']['#ajax'] = [
'event' => 'change',
'progress' => [
'type' => 'throbber',
'message' => t('Loading view details ...'),
],
'callback' => 'degov_views_argument_getter',
'wrapper' => $arguments_wrapper_selector,
'method' => 'replace',
];
$element['target_id']['#attributes']['class'][] = 'viewreference_target_id';
$element['display_id']['#attributes']['class'][] = 'viewreference_display_id';
$element['#attached']['library'][] = 'degov_paragraph_view_reference/viewsreference';
// Get arguments states to set them to entity reference field too.
$argument_states = $element['options']['argument']['#states'];
// Get extra data from serialized field.
$extra_data = [];
$values = $items->getValue();
if (!empty($values[0]['data'])) {
$extra_data = unserialize($values[0]['data']);
}
$element['page_limit'] = [
'#type' => 'number',
'#title' => t('Page limit'),
'#default_value' => !empty($extra_data['page_limit']) ? $extra_data['page_limit'] : '',
'#weight' => 10,
];
$element['argument'] = [
'#tree' => TRUE,
'0' => $element['options']['argument'],
];
$entity_type = 'node';
if (!empty($values[0]['target_id'])) {
/** @var \Drupal\views\Entity\View $view */
$view = \Drupal\views\Entity\View::load($values[0]['target_id']);
$entity_type = $view->getExecutable()->getBaseEntityType()->id();
$display_id = 'default';
if (!empty($values[0]['display_id']) && $values[0]['display_id'] != '_none') {
$display_id = $values[0]['display_id'];
}
// Get the view display.
$display = $view->getDisplay($display_id);
// Contexual arguments if they are not overriden are set only in default.
if (empty($display['display_options']['arguments'])) {
// If no arguments found try to get the ones from default display.
$display = $view->getDisplay('default');
}
$argument_values = explode('/', $values[0]['argument']);
if (!empty($display['display_options']['arguments'])) {
$num = 0;
foreach ($display['display_options']['arguments'] as $argument_name => $argument_value) {
$title_extra = '';
if ($argument_value['not']) {
$title_extra = ' (' . t('Exclude this items') . ')';
}
if ($argument_name == 'tid' && $argument_value['table'] == 'taxonomy_index') {
$element['argument'][$num] = [
'#type' => 'entity_autocomplete',
'#title' => t('Taxonomy term') . $title_extra,
'#default_value' => \Drupal\taxonomy\Entity\Term::load($argument_values[$num]),
'#target_type' => 'taxonomy_term',
'#selection_handler' => 'default:taxonomy_term',
'#selection_settings' => [],
];
$num++;
continue;
}
if ($argument_name == 'nid' && $argument_value['table'] == 'node_field_data') {
$element['argument'][$num] = [
'#type' => 'entity_autocomplete',
'#title' => t('Node') . $title_extra,
'#default_value' => \Drupal\node\Entity\Node::load($argument_values[$num]),
'#target_type' => 'node',
'#selection_handler' => 'default:node',
'#selection_settings' => [],
];
$num++;
continue;
}
if ($argument_name == 'uid' && $argument_value['table'] == 'node_field_data') {
$element['argument'][$num] = [
'#type' => 'entity_autocomplete',
'#title' => t('User') . $title_extra,
'#default_value' => \Drupal\user\Entity\User::load($argument_values[$num]),
'#target_type' => 'user',
'#selection_handler' => 'default:user',
'#selection_settings' => [],
];
$num++;
continue;
}
// Get field info.
$info = _views_argument_field_info($argument_value);
$field_info = $info['info'];
$bundle_info = $info['bundle_info'];
if ($field_info) {
$element['argument'][$num] = [
'#type' => ($field_info->getType() == 'entity_reference') ? 'entity_autocomplete' : 'textfield',
'#title' => empty($bundle_info) ? $field_info->getLabel() : $bundle_info->getLabel(),
'#description' => empty($bundle_info) ? $field_info->getDescription() : $bundle_info->getDescription(),
'#default_value' => !empty($argument_values[$num]) ? $argument_values[$num] : '',
];
$element['argument'][$num]['#title'] .= $title_extra;
// If it is entity reference and some more settings.
if (($field_info->getType() == 'entity_reference')) {
$info_settings = $field_info->getSettings();
$bundle_settings = $bundle_info->getSettings();
$element['argument'][$num]['#target_type'] = $info_settings['target_type'];
$element['argument'][$num]['#selection_handler'] = $bundle_settings['handler'];
$element['argument'][$num]['#selection_settings'] = [];
$element['argument'][$num]['#selection_settings']['target_bundles'] = $bundle_settings['handler_settings']['target_bundles'];
// Default value could be only entity, let's load one.
$entity_storage = \Drupal::entityManager()
->getStorage($info_settings['target_type']);
$entity = $entity_storage->load($element['argument'][$num]['#default_value']);
$element['argument'][$num]['#default_value'] = $entity ? $entity : '';
}
}
else {
// This is not field but property of the entity.
$property = array_shift($argument);
$element['argument'][$num] = [
'#type' => 'textfield',
'#title' => $property['field'],
'#default_value' => !empty($argument_values[$num]) ? $argument_values[$num] : '',
];
}
$num++;
}
}
}
$element['argument']['#prefix'] = '<details id="' . $arguments_wrapper_selector . '_arg" class="form-wrapper">';
$element['argument']['#prefix'] .= '<summary role="button" aria-controls="' . $arguments_wrapper_selector . '_arg" aria-expanded="false" aria-pressed="false">' . t('View arguments') . '</summary>';
$element['argument']['#weight'] = $arguments_weight;
$element['argument']['#states'] = $argument_states;
$element['argument']['#suffix'] = '</details>';
$view_modes = ['' => t('As defined in the view')] + \Drupal::service('entity_display.repository')
->getViewModeOptions($entity_type);
if (!in_array($extra_data['view_mode'], array_keys($view_modes))) {
$extra_data['view_mode'] = 'default';
}
$element['view_mode'] = [
'#type' => 'select',
'#title' => t('Views row view mode'),
'#default_value' => !empty($extra_data['view_mode']) ? $extra_data['view_mode'] : 'default',
'#options' => $view_modes,
'#weight' => 11,
'#attributes' => ['class' => ['viewsreference_view_mode']],
];
$element['options']['#prefix'] = '<div id="' . $arguments_wrapper_selector . '" class="form-wrapper">';
$element['options']['#suffix'] = '</div>';
$element['options']['#weight'] = 100;
$element['options']['argument'] = $element['argument'];
$element['options']['view_mode'] = $element['view_mode'];
unset($element['argument']);
unset($element['view_mode']);
}
}
