function _cms_content_sync_form_alter_disabled_fields in CMS Content Sync 2.1.x
Same name and namespace in other branches
- 8 cms_content_sync.module \_cms_content_sync_form_alter_disabled_fields()
- 2.0.x cms_content_sync.module \_cms_content_sync_form_alter_disabled_fields()
Disable all form elements if the content has been pulled and the user should not be able to alter pulled content.
Parameters
array $form:
\Drupal\Core\Form\FormStateInterface $form_state: The form state to get default values from.
\Drupal\Core\Entity\EntityInterface $entity:
See also
\cms_content_sync_form_alter()
2 calls to _cms_content_sync_form_alter_disabled_fields()
- cms_content_sync_form_alter in ./
cms_content_sync.module - 1) Make sure the user is informed that content will not only be deleted on this * instance but also on all connected instances if configured that way.
- _cms_content_sync_paragraphs_push_settings_form in ./
cms_content_sync.module - Add the Push settings for to the several Paragraph widget types.
File
- ./
cms_content_sync.module, line 1344 - Module file for cms_content_sync.
Code
function _cms_content_sync_form_alter_disabled_fields(array &$form, FormStateInterface $form_state, EntityInterface $entity) {
$value_path = [];
if (!empty($form['#field_parents'])) {
$value_path = $form['#field_parents'];
}
if ($entity
->getEntityTypeId() == 'paragraph') {
$value_path[] = $entity
->get('parent_field_name')->value;
$value_path[] = $form['#delta'];
}
$value_path[] = 'cms_content_sync_edit_override';
if ($form_state
->hasValue($value_path)) {
$value = boolval($form_state
->getValue($value_path));
}
else {
$input = $form_state
->getUserInput();
foreach ($value_path as $key) {
if (empty($input[$key])) {
$input = NULL;
break;
}
$input = $input[$key];
}
$value = boolval($input);
}
$entity_status = EntityStatus::getInfosForEntity($entity
->getEntityTypeId(), $entity
->uuid());
$behavior = NULL;
$overridden = FALSE;
$pull_deletion = FALSE;
$merged_fields = [];
foreach ($entity_status as $info) {
if (!$info || !$info
->getLastPull()) {
continue;
}
if ($info
->isSourceEntity()) {
continue;
}
if (!$info
->getFlow()) {
continue;
}
$config = $info
->getFlow()
->getController()
->getEntityTypeConfig($entity
->getEntityTypeId(), $entity
->bundle());
if (isset($config['import_updates']) && ($config['import_updates'] == PullIntent::PULL_UPDATE_FORCE_AND_FORBID_EDITING || $config['import_updates'] == PullIntent::PULL_UPDATE_FORCE_UNLESS_OVERRIDDEN)) {
$behavior = $config['import_updates'];
$overridden = $info
->isOverriddenLocally() || $value;
$pull_deletion = boolval($config['import_deletion_settings']['import_deletion']);
if (EntityHandlerPluginManager::isEntityTypeFieldable($entity
->getEntityTypeId())) {
/** @var \Drupal\Core\Entity\EntityFieldManagerInterface $entityFieldManager */
$entityFieldManager = Drupal::service('entity_field.manager');
$type = $entity
->getEntityTypeId();
$bundle = $entity
->bundle();
$field_definitions = $entityFieldManager
->getFieldDefinitions($type, $bundle);
foreach ($field_definitions as $key => $definition) {
$field_config = $info
->getFlow()
->getController()
->getPropertyConfig($entity
->getEntityTypeId(), $entity
->bundle(), $key);
if (!empty($field_config['handler_settings']['merge_local_changes'])) {
$merged_fields[] = $definition
->getLabel();
}
}
}
break;
}
}
if (!$behavior) {
return;
}
$id = bin2hex(random_bytes(4));
$allow_overrides = $behavior == PullIntent::PULL_UPDATE_FORCE_UNLESS_OVERRIDDEN;
// $hide_elements = ['container', 'vertical_tabs', 'details'];.
foreach ($form as $key => $form_item) {
if (!is_array($form_item)) {
continue;
}
if (!isset($form_item['#type'])) {
continue;
}
if ($key != 'actions') {
if ($allow_overrides) {
// If we used the DISABLED attribute, we couldn't reliably remove it
// from all elements, as some should still have the attribute from other
// circumstances and we would also have to apply it nested.
// Otherwise we'd have to either submit the form and redirect to the
// edit page or reload the whole form via AJAX, conflicting with
// embedded forms.
// So instead we hide and show the elements via JavaScript, leading
// to the best usability and overall simplest / most reliable
// implementation from the options available.
$form[$key]['#attributes']['class'][] = 'cms-content-sync-edit-override-id-' . $id;
if (!$overridden) {
$form[$key]['#attributes']['class'][] = 'cms-content-sync-edit-override-hide';
}
}
else {
if ($form[$key]['#type'] != 'hidden' && $form[$key]['#type'] != 'token' && empty($form[$key]['#disabled'])) {
if ($key == 'menu') {
$allow = TRUE;
$menu_link_manager = Drupal::service('plugin.manager.menu.link');
/**
* @var \Drupal\Core\Menu\MenuLinkManager $menu_link_manager
*/
$menu_items = $menu_link_manager
->loadLinksByRoute('entity.' . $entity
->getEntityTypeId() . '.canonical', [
$entity
->getEntityTypeId() => $entity
->id(),
]);
foreach ($menu_items as $menu_item) {
if (!$menu_item instanceof MenuLinkContent) {
continue;
}
/**
* @var \Drupal\menu_link_content\Entity\MenuLinkContent $item
*/
$item = Drupal::service('entity.repository')
->loadEntityByUuid('menu_link_content', $menu_item
->getDerivativeId());
if (!$item) {
continue;
}
$entity_status = EntityStatus::getInfosForEntity($item
->getEntityTypeId(), $item
->uuid());
foreach ($entity_status as $info) {
if (!$info || !$info
->getLastPull()) {
continue;
}
if ($info
->isSourceEntity()) {
continue;
}
if (!$info
->getFlow()) {
continue;
}
$config = $info
->getFlow()
->getController()
->getEntityTypeConfig($item
->getEntityTypeId(), $item
->bundle());
if ($config['import_updates'] == PullIntent::PULL_UPDATE_FORCE_AND_FORBID_EDITING || $config['import_updates'] == PullIntent::PULL_UPDATE_FORCE_UNLESS_OVERRIDDEN && !$info
->isOverriddenLocally()) {
$allow = FALSE;
}
}
}
if ($allow) {
continue;
}
}
// This will transform the field from being disabled to being readonly instead. This will interfere with
// Drupal's default behavior however, so we leave it out by default.
// $form[$key]['#attributes']['class'][] = 'cms-content-sync-edit-override-disabled';.
$form[$key]['#disabled'] = TRUE;
}
}
}
// Disable entity actions for the core layout builder.
$form_object = $form_state
->getFormObject();
if ($key == 'actions' && $form_object instanceof OverridesEntityForm) {
if ($behavior == PullIntent::PULL_UPDATE_FORCE_AND_FORBID_EDITING) {
$form['actions']['submit']['#attributes']['disabled'] = 'disabled';
$form['actions']['discard_changes']['#attributes']['disabled'] = 'disabled';
$form['actions']['revert']['#attributes']['disabled'] = 'disabled';
}
}
// Disable the submit button when the editing of the entity is forbidden.
if ($key == 'actions' && $behavior == PullIntent::PULL_UPDATE_FORCE_AND_FORBID_EDITING) {
$form['actions']['submit']['#attributes']['disabled'] = 'disabled';
}
}
$is_embedded = $entity
->getEntityTypeId() == 'paragraph';
if ($allow_overrides) {
$form['cms_content_sync_edit_override'] = [
'#type' => 'checkbox',
'#default_value' => $overridden,
'#weight' => -10000,
'#title' => t('Overwrite locally and ignore future remote updates'),
'#description' => t('%label has been pulled and future remote updates would overwrite local changes.<br>Checking this will make sure that future remote updates will be ignored so your local changes persist.<br>Unchecking this will immediately reset all local changes.', [
'%label' => $is_embedded ? t('This content') : $entity
->label(),
]) . (count($merged_fields) ? '<br>' . t('Changes to @name will still be merged.', [
'@name' => implode(', ', $merged_fields),
]) : '') . ($pull_deletion ? '<br><strong>' . t('If the remote content is deleted, this content will also be deleted locally.') . '</strong>' : ''),
'#attributes' => [
'class' => [
'cms-content-sync-edit-override',
],
'data-cms-content-sync-edit-override-id' => $id,
],
];
$form['cms_content_sync_edit_override__entity_type'] = [
'#type' => 'hidden',
'#value' => $entity
->getEntityTypeId(),
];
$form['cms_content_sync_edit_override__entity_uuid'] = [
'#type' => 'hidden',
'#value' => $entity
->uuid(),
];
$form['actions']['submit']['#submit'][] = '_cms_content_sync_override_entity_submit';
}
elseif (!$is_embedded) {
$messenger = Drupal::messenger();
$messenger
->addWarning(t('%label cannot be edited as it has been pulled.', [
'%label' => $entity
->label(),
]));
}
}