Last active
March 25, 2024 18:26
-
-
Save krisahil/ca9ff8d1b02f3fe8b417e5a0944c1642 to your computer and use it in GitHub Desktop.
Drupal: Form mode switcher for imported content
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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