View source
<?php
namespace Drupal\entityconnect;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\entityconnect\Form\AdministrationForm;
use Drupal\field\Entity\FieldConfig;
class EntityconnectFormUtils {
public static function fieldConfigEditFormAlter(array &$form, FormStateInterface $form_state) {
$field = $form_state
->getFormObject()
->getEntity();
$type = $field
->getType();
if ($type == 'entity_reference') {
$defaults = $field
->getThirdPartySettings('entityconnect');
if (!$defaults) {
$config = \Drupal::config('entityconnect.administration_config');
$defaults = $config
->get();
}
AdministrationForm::attach($form['third_party_settings'], $defaults);
}
}
public static function entityFormAlter(array &$form, FormStateInterface $form_state) {
$ref_fields = static::getReferenceFields($form, $form_state);
if ($ref_fields) {
foreach ($ref_fields as $field) {
$elementInfo = \Drupal::service('element_info');
$form[$field]['#process'] = array_merge($elementInfo
->getInfoProperty($form[$field]['#type'], '#process', []), [
[
'\\Drupal\\entityconnect\\EntityconnectWidgetProcessor',
'process',
],
]);
$form['#validate'] = !isset($form['#validate']) ? [] : $form['#validate'];
array_unshift($form['#validate'], [
'\\Drupal\\entityconnect\\EntityconnectFormUtils',
'validateForm',
]);
}
}
}
public static function validateForm(array &$form, FormStateInterface $form_state) {
$ref_fields = static::getReferenceFields($form, $form_state);
foreach ($ref_fields as $field) {
$path = array_merge($form['#parents'], [
$field,
]);
$key_exists = NULL;
$ref_values = NestedArray::getValue($form_state
->getValues(), $path, $key_exists);
if ($key_exists) {
foreach ($ref_values as $key => $value) {
if (strpos($key, '_entityconnect') !== FALSE) {
$form_state
->unsetValue(array_merge($path, [
$key,
]));
}
}
}
}
}
public static function getReferenceFields(array &$form, FormStateInterface $form_state) {
$ref_fields = [];
$entity = NULL;
if (method_exists($form_state
->getFormObject(), 'getEntity')) {
$entity = $form_state
->getFormObject()
->getEntity();
}
if (empty($entity) || !$entity
->getEntityType()
->entityClassImplements('\\Drupal\\Core\\Entity\\FieldableEntityInterface')) {
return $ref_fields;
}
$field_defs = $entity
->getFieldDefinitions();
foreach (Element::getVisibleChildren($form) as $child) {
if (!isset($field_defs[$child])) {
continue;
}
$field_definition = $field_defs[$child];
if ($field_definition
->getType() == 'entity_reference') {
if ($field_definition instanceof FieldConfig) {
$ref_fields[] = $child;
}
}
}
\Drupal::moduleHandler()
->alter('entityconnect_ref_fields', $ref_fields);
return $ref_fields;
}
public static function childFormAlter(array &$form, FormStateInterface $form_state, $form_id, $cache_id) {
$exclude_forms = [
'search_block_form',
];
\Drupal::moduleHandler()
->alter('entityconnect_exclude_forms', $exclude_forms);
if (in_array($form_id, $exclude_forms)) {
return;
}
$form['parent_build_cache_id'] = [
'#type' => 'value',
'#value' => $cache_id,
];
$form['actions']['cancel'] = [
'#type' => 'submit',
'#value' => t('Cancel'),
'#submit' => [
[
'\\Drupal\\entityconnect\\EntityconnectFormUtils',
'childFormCancel',
],
],
'#parent_build_cache_id' => $cache_id,
'#limit_validation_errors' => [],
'#weight' => 1000,
];
if (isset($form['submit']['#submit'])) {
$form['submit']['#submit'][] = [
'\\Drupal\\entityconnect\\EntityconnectFormUtils',
'childFormSubmit',
];
}
else {
foreach (array_keys($form['actions']) as $action) {
if (!in_array($action, [
'preview',
'delete',
]) && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
$form['actions'][$action]['#submit'][] = [
'\\Drupal\\entityconnect\\EntityconnectFormUtils',
'childFormSubmit',
];
}
}
}
if (!empty($form['actions']['delete']) && !empty($form['actions']['delete']['#type']) && strpos($form_id, '_confirm_delete') === FALSE && strpos($form_id, 'delete_form') === FALSE) {
$delete_button =& $form['actions']['delete'];
if ($delete_button['#type'] == 'link') {
$url =& $delete_button['#url'];
$url
->setOption('query', [
'build_cache_id' => $cache_id,
'child' => 1,
]);
}
elseif ($delete_button['#type'] == 'submit') {
$form['actions']['delete']['#submit'][] = [
'\\Drupal\\entityconnect\\EntityconnectFormUtils',
'childFormDeleteSubmit',
];
}
}
$data = [
'form' => &$form,
'form_state' => &$form_state,
'form_id' => $form_id,
];
\Drupal::moduleHandler()
->alter('entityconnect_child_form', $data);
}
public static function returnFormAlter(array &$form, FormStateInterface $form_state, array $cache_data) {
if (empty($form_state
->get('#entityconnect_processed'))) {
$old_form = $cache_data['form'];
$old_form_state = $cache_data['form_state'];
$form_state
->setStorage($old_form_state
->getStorage());
$form_state
->setUserInput($old_form_state
->getUserInput());
$triggeringElement = $old_form_state
->getTriggeringElement();
$parents = is_array($triggeringElement) && !empty($triggeringElement['#array_parents']) ? $triggeringElement['#array_parents'] : NULL;
$key_exists = NULL;
$widget_container = EntityconnectNestedArray::getValue($old_form, $parents, $key_exists);
if ($key_exists) {
if (isset($widget_container['widget'])) {
$widget_container = $widget_container['widget'];
}
}
else {
return;
}
$parents = $widget_container['#parents'];
$widget_container_type = isset($widget_container['#type']) ? $widget_container['#type'] : 'autocomplete';
$field_info = $cache_data['field_info'];
if (isset($cache_data['target_id']) && empty($cache_data['cancel'])) {
$entity_type = $cache_data['target_entity_type'];
$entity_storage = \Drupal::entityTypeManager()
->getStorage($entity_type);
$entity = $entity_storage
->load($cache_data['target_id']);
if ($cache_data['target_id']) {
$target_id = $entity ? $entity
->id() : '';
switch ($widget_container_type) {
case 'autocomplete':
if ($field_info
->getType() == 'entity_reference') {
$element['target_id'] = $target_id ? sprintf('%s (%s)', $entity
->label(), $target_id) : '';
if ($element['target_id'] && !empty($widget_container['target_id']['#tags']) && !empty($widget_container['target_id']['#value'])) {
$element['target_id'] .= ', ' . $widget_container['target_id']['#value'];
}
}
break;
case 'select':
if ($widget_container['#multiple'] == FALSE || !$target_id) {
$element['target_id'] = $target_id;
}
else {
$element['target_id'] = $widget_container['#value'] + [
$target_id => $target_id,
];
}
break;
case 'radios':
$element['target_id'] = $target_id;
break;
case 'checkboxes':
$element['target_id'] = $widget_container['#value'];
if ($target_id) {
$element['target_id'] += [
$target_id => $target_id,
];
}
break;
default:
$data = [
'data' => &$cache_data,
'widget_container' => $widget_container,
'widget_container_type' => $widget_container_type,
'field_info' => $field_info,
'element_value' => NULL,
];
\Drupal::moduleHandler()
->alter('entityconnect_return_form', $data);
break;
}
}
$input = $form_state
->getUserInput();
if (isset($element)) {
static::alterFormStateInput($input, $widget_container_type, $parents, $element['target_id']);
}
elseif (!empty($data['element_value'])) {
static::alterFormStateInput($input, $widget_container_type, $parents, $data['element_value']);
}
$form_state
->setUserInput($input);
}
$form_state
->setRebuild();
$form_state
->setRequestMethod('POST');
$form_state
->set('#entityconnect_processed', TRUE);
}
}
public static function childFormCancel(array $form, FormStateInterface $form_state) {
$triggeringElement = $form_state
->getTriggeringElement();
$cache_id = $triggeringElement['#parent_build_cache_id'];
if ($cache_id && \Drupal::getContainer()
->get('entityconnect.cache')
->get($cache_id)) {
$form_state
->setRedirect('entityconnect.return', [
'cache_id' => $cache_id,
'cancel' => 1,
]);
}
}
public static function childFormSubmit(array $form, FormStateInterface $form_state) {
$cache_id = $form_state
->getValue('parent_build_cache_id');
if ($cache_id && ($cache_data = \Drupal::getContainer()
->get('entityconnect.cache')
->get($cache_id))) {
$entity = $form_state
->getFormObject()
->getEntity();
if ($entity) {
$cache_data['target_id'] = $entity
->id();
}
else {
$entity_type = $cache_data['target_entity_type'];
$data = [
'form' => &$form,
'form_state' => &$form_state,
'entity_type' => $entity_type,
'data' => &$cache_data,
];
\Drupal::moduleHandler()
->alter('entityconnect_child_form_submit', $data);
}
\Drupal::getContainer()
->get('entityconnect.cache')
->set($cache_id, $cache_data);
$form_state
->setRedirect('entityconnect.return', [
'cache_id' => $cache_id,
]);
}
}
public static function childFormDeleteSubmit(array $form, FormStateInterface $form_state) {
$triggering_element = $form_state
->getTriggeringElement();
if (in_array('delete', $triggering_element['#parents'])) {
$redirect = $form_state
->getRedirect();
$query = $redirect
->getOption('query');
if (!is_array($query)) {
$query = [];
}
$redirect
->setOption('query', $query + [
'build_cache_id' => $form_state
->getValue('parent_build_cache_id'),
'child' => 1,
]);
}
}
public static function alterFormStateInput(array &$input, $widget_type, array $parents, $element) {
switch ($widget_type) {
case 'autocomplete':
case 'multiple_selects':
array_push($parents, 'target_id');
break;
case 'textfield':
case 'radios':
case 'checkboxes':
default:
break;
}
EntityconnectNestedArray::setValue($input, $parents, $element);
}
}