Skip to content

Commit

Permalink
Updated auto_entitylabel and tragedy_commons
Browse files Browse the repository at this point in the history
  • Loading branch information
dmundra committed Aug 18, 2024
1 parent 84821eb commit 01f8672
Show file tree
Hide file tree
Showing 34 changed files with 2,089 additions and 74 deletions.
28 changes: 14 additions & 14 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion modules/auto_entitylabel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,4 @@ Current maintainers:
- Pravin raj [@Pravin Ajaaz](https://www.drupal.org/u/pravin-ajaaz)
- Purushotam Rai [@purushotam.rai](https://www.drupal.org/u/purushotamrai)
- Vladimir Roudakov [@VladimirAus](https://www.drupal.org/u/vladimiraus)
- Martin Anderson-Clutz [@mandclu](https://www.drupal.org/u/mandclu)
- Martin Anderson-Clutz [@mandclu](https://www.drupal.org/u/mandclu)
6 changes: 3 additions & 3 deletions modules/auto_entitylabel/auto_entitylabel.info.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package: Entity
type: module
core_version_requirement: ^10.1 || ^11

# Information added by Drupal.org packaging script on 2024-06-07
version: '8.x-3.2'
# Information added by Drupal.org packaging script on 2024-08-12
version: '8.x-3.3'
project: 'auto_entitylabel'
datestamp: 1717752310
datestamp: 1723462800
72 changes: 72 additions & 0 deletions modules/auto_entitylabel/auto_entitylabel.install
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@
* Install, update and uninstall functions for the Automatic Entity Labels.
*/

use Drupal\auto_entitylabel\AutoEntityLabelManager;

/**
* Implements hook_install().
*/
function auto_entitylabel_install() {
module_set_weight('auto_entitylabel', -100);
}

/**
* Implements hook_update_N().
*/
Expand Down Expand Up @@ -81,6 +90,69 @@ function auto_entitylabel_update_8201() {
$old_config->delete();
}

/**
* Sets the new "New content behavior" config option to all existing
* configurations using "Create label after first save" as the initial value,
* which preserves the old logic, that content is saved twice, (which may
* interfere with other modules, but all tokens are supported).
*
* NOTE, if you desire to switch to the new logic, which creates the label
* before saving the content (doesn't interfere with other modules, but not
* all tokens are supported), set the "New content behavior" to
* "Create label before first save" in your "automatic label" settings.
*/
function auto_entitylabel_update_8202() {
/** @var \Drupal\Core\Entity\EntityTypeManager $entity_type_manager */
$entity_type_manager = \Drupal::entityTypeManager();

$entity_types = [];
/** @var \Drupal\Core\Config\Entity\ConfigEntityType $entity_type */
foreach ($entity_type_manager->getDefinitions() as $entity_type_id => $entity_type) {
if ($entity_type->getLinkTemplate('auto-label')) {
$entity_types[] = $entity_type_id;
}
}

$bundleService = \Drupal::service('entity_type.bundle.info');

/** @var \Drupal\Core\Config\ConfigFactory $config_interface */
$config_interface = \Drupal::service('config.factory');
$existingConfigs = $config_interface->listAll('auto_entitylabel.settings');

foreach ($entity_types as $type_id) {
$type = $entity_type_manager->getStorage($type_id)->getEntityType()->getProvider();

// Special handling for paragraphs because the module had to
// be different.
if ($type == 'paragraphs') {
$type = 'paragraph';
}

$bundles = array_keys($bundleService->getBundleInfo($type));

foreach ($bundles as $bundle) {
$config_name = "auto_entitylabel.settings.$type.$bundle";

if (in_array($config_name, $existingConfigs)) {
$config = $config_interface->getEditable($config_name);
// There are two values for the new entity action: 0 means
// set the label before first save, 1 means after first
// save. Preserve the previous behaviour and default to
// after first save.
$config->set('new_content_behavior', AutoEntityLabelManager::AFTER_SAVE);
$config->save();
}
}
}
}

/**
* Lower module weight so to run before other modules.
*/
function auto_entitylabel_update_8301(&$sandbox) {
module_set_weight('auto_entitylabel', -100);
}

/**
* Implements hook_uninstall().
*/
Expand Down
165 changes: 155 additions & 10 deletions modules/auto_entitylabel/auto_entitylabel.module
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
*/

use Drupal\auto_entitylabel\AutoEntityLabelManager;
use Drupal\Component\Render\MarkupInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityFormInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Markup;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;

Expand Down Expand Up @@ -168,9 +170,78 @@ function auto_entitylabel_entity_presave(EntityInterface $entity) {
$decorator = \Drupal::service('auto_entitylabel.entity_decorator');
/** @var \Drupal\auto_entitylabel\AutoEntityLabelManager $decorated_entity */
$decorated_entity = $decorator->decorate($entity);
if ($decorated_entity->hasLabel() && $decorated_entity->autoLabelNeeded()
&& !$decorated_entity->isTitlePreserved()) {
$decorated_entity->setLabel();
if ($decorated_entity->hasLabel() && $decorated_entity->autoLabelNeeded()) {

// Need to generate a label for this entity.
//
// There's a few cases we need to handle.
// I'm going to lay these out explicitly so that the logic is
// clear. I expect we can optimise these at a later point.
//
// Two of the scenarios need the placeholder label, so
// always generate it.
// Make the placeholder unique for this entity. Handles the case
// where both a paragraph on a node and a node have an auto label.
$placeholder = strtr('%AutoEntityLabel: @entityId%', ['@entityId' => $entity->uuid()]);

// Check to see if this is a new entity.
if ($entity->isNew()) {
// Handle the case where the automatic label is optional.
// Check to see if isTitlePreserved is set. If the autolabel is
// optional AND the user has filled this title in then the
// the autolabel should not be set.
if (!$decorated_entity->isTitlePreserved() || $entity->label() == '%AutoEntityLabel%') {
// For a new entity check to see whether the automatic label
// is configured to be generated before we've saved the node
// to the database or after. While the entity is flagged as
// new this presave is running before the entity has been saved
// to the database.
if ($decorated_entity->getNewContentBehavior() === AutoEntityLabelManager::BEFORE_SAVE) {
// Generate the automatic label during this run of the presave
// hook. Note that not all tokens are available during the
// first presave hook run for new entities (most notably the
// entity id token).
$decorated_entity->setLabel();
}
else {
// Generate the label after the first save, when the entity has
// been written to the database and all tokens are available.
// When the after first save option is selected code in the
// autoentity_entity_insert function will trigger a resave of the
// entity, which will in turn trigger another run of this presave
// hook (but during the second run the entity will not be new).
// To allow the entity to save we'll set a placeholder title,
// one that will be replaced once the entity is resaved.
// Using Drupal functions so as not to trigger two runs of
// setLabel().
$label_field = $entity->getEntityType()->getKey('label');
$entity->set($label_field, $placeholder);
}
}
}
else {
// This is an update of an existing entity.
// Check to see whether the existing title needs to be
// preserved.
if ($decorated_entity->isTitlePreserved()) {
// The existing title needs to be preserved.
// Now check whether or not the title is the new entity
// placeholder. Because if it is we want to ignore
// the isTitlePreserved flag and update the label anyway
// (the code assumes that the only way the entity will
// have the placeholder title is if we've configured this entity
// to set its auto label during the second run of the presave
// hook and this is that second run).
$oldLabel = $entity->label();
if ($oldLabel == $placeholder) {
$decorated_entity->setLabel();
}
}
else {
// Don't preserve the exiting title. Update the label.
$decorated_entity->setLabel();
}
}
}
}
}
Expand All @@ -179,20 +250,94 @@ function auto_entitylabel_entity_presave(EntityInterface $entity) {
* Implements hook_entity_insert().
*/
function auto_entitylabel_entity_insert(EntityInterface $entity) {
// AutoEntityLabel only supports content entities.
if ($entity instanceof ContentEntityInterface) {
// To support tokens that are only available after the entity has
// been created (like id tokens) trigger a second save.
// To do this without corrupting the entity run the
// save operation at the end of the entity insert transaction.
// To run code at the entity of the entity insert transaction
// we need to register a transaction shutdown function.
// Check the autolabel settings for the entity to see if we
// need to register the shutdown function.
$decorator = \Drupal::service('auto_entitylabel.entity_decorator');
/** @var \Drupal\auto_entitylabel\AutoEntityLabelManager $decorated_entity */
$decorated_entity = $decorator->decorate($entity);
if ($decorated_entity->hasLabel()
&& (
$decorated_entity->hasAutoLabel()
|| empty($entity->label()) && $decorated_entity->hasOptionalAutoLabel()
)
&& $decorated_entity->autoLabelNeeded()
&& $decorated_entity->getNewContentBehavior() === AutoEntityLabelManager::AFTER_SAVE
) {
if ($entity->getEntityType()->isRevisionable()) {
$entity->setNewRevision(FALSE);
// This new entity has an autolabel and it needs to be generated
// after the entity has been saved in the database. Register the
// shutdown function.
drupal_register_shutdown_function('_auto_entitylabel_post_insert', $entity);

// Set entity label in memory so messages and such can use what will be
// saved during shutdown.
$decorator = \Drupal::service('auto_entitylabel.entity_decorator');
/** @var \Drupal\auto_entitylabel\AutoEntityLabelManager $decorated_entity */
$decorated_entity = $decorator->decorate($entity);
if ($decorated_entity->hasLabel() && $decorated_entity->autoLabelNeeded()) {
$placeholder = strtr('%AutoEntityLabel: @entityId%', ['@entityId' => $entity->uuid()]);
if (!$decorated_entity->isTitlePreserved() || $entity->label() == $placeholder) {
if ($decorated_entity->getNewContentBehavior() === AutoEntityLabelManager::AFTER_SAVE) {
// Update entity's label in memory for anything running after us.
$label = $decorated_entity->setLabel();

// Update messages that were using the placeholder label.
$messenger = Drupal::messenger();
$all_messages = $messenger->all();
$messenger->deleteAll();
foreach ($all_messages as $type => $messages) {
foreach ($messages as $message) {
if (strpos($message, $placeholder) >= 0) {
if ($message instanceof MarkupInterface) {
$message = Markup::create(str_replace($placeholder, $label, $message));
}
else {
$message = str_replace($placeholder, $label, $message);
}
}
$messenger->addMessage($message, $type);
}
}
}
}
}
}
}
}

/**
* Re-save the entity to trigger creation of the automatic label if necessary.
*/
function _auto_entitylabel_post_insert(EntityInterface $entityArg) {
if ($entityArg instanceof ContentEntityInterface) {
// Because of the way PHP shutdown functions work this operation may
// be called during an entity delete operation (as demonstrated by
// the Kernel test). Reload the entity from the database to check that
// it hasn't been deleted.
if ($entity = \Drupal::entityTypeManager()->getStorage($entityArg->getEntityTypeId())->loadUnchanged($entityArg->id())) {

// The entity hasn't been deleted, continue processing.
// Again because of the way shutdown functions work this
// function may be called for entities that don't have an
// autolabel or ones that do but don't need to be saved
// again. Run the same checks that were run during the
// insert hook to be sure that this entity really needs the
// second save.
$decorator = \Drupal::service('auto_entitylabel.entity_decorator');
/** @var \Drupal\auto_entitylabel\AutoEntityLabelManager $decorated_entity */
$decorated_entity = $decorator->decorate($entity);

if ($decorated_entity->hasLabel()
&& $decorated_entity->autoLabelNeeded()
&& $decorated_entity->getNewContentBehavior() === AutoEntityLabelManager::AFTER_SAVE) {
if ($entity->getEntityType()->isRevisionable()) {
$entity->setNewRevision(FALSE);
}
$entity->save();
}
$entity->save();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ auto_entitylabel.settings.*:
dependencies:
type: config_dependencies
label: 'Dependencies'
new_content_behavior:
type: integer
label: 'When to generate labels for new content'
Binary file added modules/auto_entitylabel/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions modules/auto_entitylabel/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 01f8672

Please sign in to comment.