Skip to content

Instantly share code, notes, and snippets.

@krisahil
Last active March 25, 2024 18:26
Show Gist options
  • Save krisahil/ca9ff8d1b02f3fe8b417e5a0944c1642 to your computer and use it in GitHub Desktop.
Save krisahil/ca9ff8d1b02f3fe8b417e5a0944c1642 to your computer and use it in GitHub Desktop.
Drupal: Form mode switcher for imported content
name: 'mymodule'
type: module
description: 'Demo module to show how to switch form modes for imported/migrated content'
package: Custom
core_version_requirement: ^10
dependencies:
- drupal:migrate
<?php
use \Drupal\Core\Entity\EntityInterface;
/**
* @file
* Primary module hooks for mymodule module.
*/
/**
* Implements hook_entity_form_mode_alter().
*/
function mymodule_entity_form_mode_alter(&$form_mode, EntityInterface $entity) {
// Switches imported events to the "imported" form mode,
// which restricts someone from editing imported fields (because their changes
// would be overwritten if source data gets updated).
if ($entity->getEntityTypeId() === 'node' && $entity->bundle() === 'event') {
if (!$entity->isNew()) {
// Provides an "escape hatch" in case you want to disable this form mode
// switcher.
if (!_mymodule_event_can_switch_mode_form()) {
return;
}
if (_mymodule_event_has_been_imported($entity->id())) {
// See mymodule_entity_extra_field_info() and
// mymodule_form_node_event_edit_form_alter() for a visual indicator
// that this view mode has been switched.
$form_mode = 'imported';
}
}
}
}
/**
* Determines whether the events form mode switcher is enabled.
*
* It is enabled by default, but someone can disable it without a code change:
* @code
* drush state:set mymodule.events_form_mode_switcher_enabled 0 --input-format=boolean
* @endcode
*
* @return bool
* Returns true if this feature is enabled (default is enabled).
*
* @see https://www.drupal.org/docs/develop/drupal-apis/state-api/state-api-overview
*/
function _mymodule_event_can_switch_mode_form(): bool {
return (bool) \Drupal::state()->get('mymodule.events_form_mode_switcher_enabled', TRUE);
}
/**
* Determines whether a node was imported by the events migration.
*
* @param string $node_id
* The node's ID.
*
* @return bool
* Returns true if this node was migrated as part of migration
* `mymodule_events`.
*
* @throws \Drupal\Component\Plugin\Exception\PluginException
*/
function _mymodule_event_has_been_imported(string $node_id): bool {
$migration_id = 'mymodule_events';
/** @var \Drupal\migrate\Plugin\MigrationPluginManagerInterface $service */
$service = \Drupal::service('plugin.manager.migration');
/** @var \Drupal\migrate\Plugin\MigrationInterface $migration */
$migration = $service->createInstance($migration_id);
if ($migration) {
$migration->getIdMap()->getQualifiedMapTableName();
$source_values = $migration->getIdMap()->lookupSourceId(['nid' => $node_id]);
return count($source_values) > 0;
}
return FALSE;
}
/**
* Implements hook_entity_extra_field_info().
*/
function mymodule_entity_extra_field_info() {
$extra = [];
$extra['node']['event']['form']['mymodule_form_mode_override_notice'] = [
'label' => t('MyModule: Form mode override notice'),
'description' => t('Alerts the user that this node has been imported, so certain fields may be read-only.'),
'visible' => TRUE,
'weight' => 0,
];
return $extra;
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function mymodule_form_node_event_edit_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
// Bail early if our notice is not even configured to display in this form
// mode.
if (!$form_state->get('form_display')->getComponent('mymodule_form_mode_override_notice')) {
return;
}
// We only care about imported nodes.
$form_object = $form_state->getFormObject();
/** @var \Drupal\node\NodeInterface $node */
$node = $form_object->getEntity();
if (!_mymodule_event_has_been_imported($node->id())) {
return;
}
// Is the form mode switcher activated?
if (_mymodule_event_can_switch_mode_form()) {
$message = t('This item has been imported, so some fields cannot be edited.');
}
else {
$message = t('Although this item has been imported, you can edit all fields. Use caution, because your edits could be overwritten by a future import.');
}
$form['mymodule_form_mode_override_notice'] = [
'#markup' => '<p><em><strong>Notice: </strong> ' . $message . '</em></p>',
];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment